import logger from '../utils/logger.js'
async function execute(ast, ctx, traceCollector = null, ioMethods = null, cancelToken = null) {
  // 逻辑坐标系：以画布中心为原点，x 向右为正，y 向上为正
  const centerX = ctx.canvas.width / 2;
  const centerY = ctx.canvas.height / 2;
  let x = 0, y = 0, angle = 0;   // 画笔笔尖在"逻辑坐标系"中的位置与角度（角度：0 向上，逆时针为正）
  const publishPen = typeof window !== 'undefined' && typeof window.__gocUpdatePen === 'function'
    ? window.__gocUpdatePen
    : null;
  const setPenVisible = typeof window !== 'undefined' && typeof window.__gocSetPenVisible === 'function'
    ? window.__gocSetPenVisible
    : null;

  function toCanvasX(logicalX) {
    return centerX + logicalX;
  }
  function toCanvasY(logicalY) {
    return centerY - logicalY;
  }

  // 计算画笔中心位置（相对于笔尖）
  function getPenCenterOffset() {
    // 假设画笔长度为20像素，中心在笔尖后方
    const penLength = 20;
    const centerX = -penLength * Math.sin(angle * Math.PI / 180);
    const centerY = -penLength * Math.cos(angle * Math.PI / 180);
    return { centerX, centerY };
  }

  // 获取画笔中心位置（用于显示画笔）
  function getPenCenterPosition() {
    const { centerX, centerY } = getPenCenterOffset();
    return {
      x: x + centerX,
      y: y + centerY
    };
  }

  // 更新画笔显示位置（传递中心位置给前端）
  function updatePenDisplay(penX = x, penY = y, penAngle = angle) {
    if (publishPen) {
      // 临时保存当前坐标
      const originalX = x;
      const originalY = y;
      const originalAngle = angle;
      
      // 使用传入的坐标计算中心位置
      x = penX;
      y = penY;
      angle = penAngle;
      
      const centerPos = getPenCenterPosition();
      publishPen(centerPos.x, centerPos.y, angle, ctx.strokeStyle || 'black', lineWidth);
      
      // 恢复原始坐标
      x = originalX;
      y = originalY;
      angle = originalAngle;
    }
  }

  let lineWidth = 4;          //当前线条宽度

  //let color = "black";

  const colorMap = {
    0: "black",      // 黑色
    1: "red",        // 红色
    2: "blue",       // 蓝色
    3: "lime",       // 亮绿色
    4: "cyan",       // 青色
    5: "yellow",     // 黄色
    6: "maroon",     // 栗色
    7: "navy",       // 深蓝色
    8: "lightgray",  // 浅灰色
    9: "pink",       // 粉色
    10: "darkgreen", // 深绿色
    11: "purple",    // 紫色
    12: "teal",      // 蓝绿色
    13: "gold",      // 金色
    14: "orange",    // 橙色
    15: "white",     // 白色
  };

  // 图片存储对象
  const imageMap = {};

  let isPenDown = true; // true 表示落笔，false 表示抬笔
  let speedLevel = window.__gocSpeedLevel || 5; // 从全局变量获取速度等级，默认5，范围1-10，1最慢，10最快

  let radius = 0;

  let radiusX = 0;
  let radiusY = 0;

  let width = 0;
  let height = 0;

  // 浮点数显示精度（用于 pen.text 数字输出），默认小数点后 2 位
  let floatPrecision = 2;
  // 文本字号（用于 pen.text 输出）；若未设置，则按线宽推导
  let textFontSize = null;
  // 文本方向：true=始终向上，false=随笔方向旋转
  let textAlwaysUp = true;
  // 文本字体：支持字体编号或字体名称
  let textFontFamily = 'sans-serif';
  // 图片方向：true=始终向上，false=随笔方向旋转
  let picAlwaysUp = true;

  // 变量存储
  const variables = {};
  // 数组存储
  const arrays = {};

  // 重置画笔状态到初始值
  x = 0;
  y = 0;
  angle = 0;
  lineWidth = 4;
  isPenDown = true;
  ctx.strokeStyle = 'blue';
  ctx.fillStyle = 'blue';
  
  // 重置其他状态变量
  speedLevel = window.__gocSpeedLevel || 5;
  floatPrecision = 2;
  textFontSize = null;
  textAlwaysUp = true;
  textFontFamily = 'sans-serif';
  picAlwaysUp = true;
  
  // 重置画笔可见性
  if (setPenVisible) {
    setPenVisible(true);
  }
  
  ctx.lineWidth = lineWidth;  // 设置初始线条宽度
  ctx.lineJoin = 'round';     // 设置线条连接为圆角，避免缺角
  ctx.lineCap = 'round';      // 设置线条端点为圆角
  ctx.beginPath();
  ctx.moveTo(toCanvasX(x), toCanvasY(y));
  updatePenDisplay();

  // 加载图片的辅助函数
  function loadImage(src) {
    logger.log("🔍 Trying to load image: ", src);
    return new Promise((resolve, reject) => {
      // 安全检查：只允许加载image文件夹中的图片
      if (!src.startsWith('image/')) {
        src = 'image/' + src;
      }

      // 进一步安全检查：防止路径遍历攻击
      if (src.includes('..') || src.includes('\\') || src.startsWith('/')) {
        reject(new Error(`Invalid image path: ${src}`));
        return;
      }

      const img = new Image();
      img.onload = () => resolve(img);
      img.onerror = () => reject(new Error(`Failed to load image: ${src}`));
      img.src = src;
    });
  }

  // 定义pen对象中所有需要前缀的方法列表
  const penMethods = [
    'up', 'down', 'fd', 'rt', 'bk', 'lt', 'moveTo', 'lineTo', 'size', 'speed', 
    'show', 'hide', 'c', 'rgb', 'picL', 'pic', 'o', 'oo', 'e', 'ee', 'r', 'rr', 
    'showXY', 'cls', 'text', 'setprecision', 'textSize', 'textU', 'picU', 'font',
    'getSpeedInfo'
  ];

  const pen = {

    // 抬笔
    up: function () {
      isPenDown = false;

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('up', []);
      }
    },

    // 落笔
    down: function () {
      isPenDown = true;

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('down', []);
      }
    },

    //前进
    fd: async function (dist) {
      checkCancellation();
      
      // 检查参数是否有效
      if (dist === undefined || dist === null || isNaN(dist)) {
        throw new Error(`错误：没有提供参数。`);
      }
      // 如果速度10，直接绘制最终结果，跳过动画
      if (speedLevel >= 10) {
        if (isPenDown) {
          ctx.beginPath();
          ctx.moveTo(toCanvasX(x), toCanvasY(y));
          x += dist * Math.sin(angle * Math.PI / 180);
          y += dist * Math.cos(angle * Math.PI / 180);
          ctx.lineTo(toCanvasX(x), toCanvasY(y));
          ctx.stroke();
        } else {
          x += dist * Math.sin(angle * Math.PI / 180);
          y += dist * Math.cos(angle * Math.PI / 180);
        }
        updatePenDisplay();
        
        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
          traceCollector.record('fd', [dist]);
        }
        return;
      }
      
      if (isPenDown) {
        // 渐进式绘制：更精细的步骤控制
        const steps = Math.max(1, Math.ceil(Math.abs(dist) / 1)); // 每1像素一步，完美同步，支持负数
        const stepSize = dist / steps;
        const totalDelay = getDelayTime();
        const stepDelay = steps > 1 ? totalDelay / (steps - 1) : 0; // 优化延时分配
        
        // 开始新的路径
        ctx.beginPath();
        ctx.moveTo(toCanvasX(x), toCanvasY(y));
        
        // 立即同步画笔位置，避免初始延迟
        updatePenDisplay(x, y, angle);
        
        for (let i = 1; i <= steps; i++) {
          checkCancellation();
          
          // 计算当前步骤的位置
          const currentDist = stepSize * i;
          const currentX = x + currentDist * Math.sin(angle * Math.PI / 180);
          const currentY = y + currentDist * Math.cos(angle * Math.PI / 180);
          
          // 同时更新画笔位置和绘制线条（完全同步）
          ctx.lineTo(toCanvasX(currentX), toCanvasY(currentY));
          ctx.stroke();
          
          // 立即更新画笔位置，确保同步
          updatePenDisplay(currentX, currentY, angle);
          
          // 等待延时，让画笔动画有时间渲染
          await sleep(stepDelay);
        }
        
        // 更新最终位置
        x += dist * Math.sin(angle * Math.PI / 180);
        y += dist * Math.cos(angle * Math.PI / 180);
        
        // 确保画笔在最终位置
        updatePenDisplay();
      } else {
        // 抬笔状态：直接移动到目标位置
        x += dist * Math.sin(angle * Math.PI / 180);
        y += dist * Math.cos(angle * Math.PI / 180);
        ctx.moveTo(toCanvasX(x), toCanvasY(y));
        
        // 更新画笔位置
        updatePenDisplay();
        
        // 等待延时
        await sleep(getDelayTime());
      }

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('fd', [dist]);
      }
    },

    //右转
    rt: async function (deg) {
      checkCancellation();
      
      // 检查参数是否有效
      if (deg === undefined || deg === null || isNaN(deg)) {
        throw new Error(`错误：没有提供参数。`);
      }
      
      // 如果速度10，直接旋转到最终角度，跳过动画
      if (speedLevel >= 10) {
        angle += deg;
        angle = ((angle % 360) + 360) % 360;
        updatePenDisplay();
        
        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
          traceCollector.record('rt', [deg]);
        }
        return;
      }
      
      // 渐进式旋转：分步骤旋转，使动画更流畅
      const steps = Math.max(1, Math.ceil(deg / 2)); // 每2度一步，更精细
      const stepSize = deg / steps;
      const totalDelay = getDelayTime() / 2; // 旋转速度是移动速度的两倍
      const stepDelay = steps > 1 ? totalDelay / (steps - 1) : 0; // 优化延时分配
      
      for (let i = 1; i <= steps; i++) {
        checkCancellation();
        
        // 计算当前步骤的角度
        const currentDeg = stepSize * i;
        const currentAngle = ((angle + currentDeg) % 360 + 360) % 360;
        
        // 更新画笔位置显示
        updatePenDisplay(x, y, currentAngle);
        
        // 等待延时（除了最后一步）
        if (i < steps) {
          await sleep(stepDelay);
        }
      }
      
      // 更新最终角度
      angle += deg;
      angle = ((angle % 360) + 360) % 360;
      
      // 确保画笔在最终位置
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('rt', [deg]);
      }
    },

    //后退
    bk: async function (dist) {
      checkCancellation();
      
      // 检查参数是否有效
      if (dist === undefined || dist === null || isNaN(dist)) {
        throw new Error(`错误：没有提供参数。`);
      }
      
      // 如果速度10，直接绘制最终结果，跳过动画
      if (speedLevel >= 10) {
        if (isPenDown) {
          ctx.beginPath();
          ctx.moveTo(toCanvasX(x), toCanvasY(y));
          x -= dist * Math.sin(angle * Math.PI / 180);
          y -= dist * Math.cos(angle * Math.PI / 180);
          ctx.lineTo(toCanvasX(x), toCanvasY(y));
          ctx.stroke();
        } else {
          x -= dist * Math.sin(angle * Math.PI / 180);
          y -= dist * Math.cos(angle * Math.PI / 180);
        }
        updatePenDisplay();
        
        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
          traceCollector.record('bk', [dist]);
        }
        return;
      }
      
      if (isPenDown) {
        // 渐进式绘制：更精细的步骤控制
        const steps = Math.max(1, Math.ceil(Math.abs(dist) / 1)); // 每1像素一步，完美同步，支持负数
        const stepSize = dist / steps;
        const totalDelay = getDelayTime();
        const stepDelay = steps > 1 ? totalDelay / (steps - 1) : 0; // 优化延时分配
        
        // 开始新的路径
        ctx.beginPath();
        ctx.moveTo(toCanvasX(x), toCanvasY(y));
        
        // 立即同步画笔位置，避免初始延迟
        updatePenDisplay(x, y, angle);
        
        for (let i = 1; i <= steps; i++) {
          checkCancellation();
          
          // 计算当前步骤的位置
          const currentDist = stepSize * i;
          const currentX = x - currentDist * Math.sin(angle * Math.PI / 180);
          const currentY = y - currentDist * Math.cos(angle * Math.PI / 180);
          
          // 同时更新画笔位置和绘制线条（完全同步）
          ctx.lineTo(toCanvasX(currentX), toCanvasY(currentY));
          ctx.stroke();
          
          // 立即更新画笔位置，确保同步
          updatePenDisplay(currentX, currentY, angle);
          
          // 等待延时，让画笔动画有时间渲染
          await sleep(stepDelay);
        }
        
        // 更新最终位置
        x -= dist * Math.sin(angle * Math.PI / 180);
        y -= dist * Math.cos(angle * Math.PI / 180);
        
        // 确保画笔在最终位置
        updatePenDisplay();
      } else {
        // 抬笔状态：直接移动到目标位置
        x -= dist * Math.sin(angle * Math.PI / 180);
        y -= dist * Math.cos(angle * Math.PI / 180);
        ctx.moveTo(toCanvasX(x), toCanvasY(y));
        
        // 更新画笔位置
        updatePenDisplay();
        
        // 等待延时
        await sleep(getDelayTime());
      }

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('bk', [dist]);
      }
    },

    //左转
    lt: async function (deg) {
      checkCancellation();
      
      // 检查参数是否有效
      if (deg === undefined || deg === null || isNaN(deg)) {
        throw new Error(`错误：命令 'pen.lt' 需要有效的数字参数，但没有提供参数。请使用 'pen.lt(角度);' 而不是 'pen.lt();'。`);
      }
      
      // 如果速度10，直接旋转到最终角度，跳过动画
      if (speedLevel >= 10) {
        angle -= deg;
        angle = ((angle % 360) + 360) % 360;
        updatePenDisplay();
        
        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
          traceCollector.record('lt', [deg]);
        }
        return;
      }
      
      // 渐进式旋转：分步骤旋转，使动画更流畅
      const steps = Math.max(1, Math.ceil(deg / 2)); // 每2度一步，更精细
      const stepSize = deg / steps;
      const totalDelay = getDelayTime() / 2; // 旋转速度是移动速度的两倍
      const stepDelay = steps > 1 ? totalDelay / (steps - 1) : 0; // 优化延时分配
      
      for (let i = 1; i <= steps; i++) {
        checkCancellation();
        
        // 计算当前步骤的角度
        const currentDeg = stepSize * i;
        const currentAngle = ((angle - currentDeg) % 360 + 360) % 360;
        
        // 更新画笔位置显示
        updatePenDisplay(x, y, currentAngle);
        
        // 等待延时（除了最后一步）
        if (i < steps) {
          await sleep(stepDelay);
        }
      }
      
      // 更新最终角度
      angle -= deg;
      angle = ((angle % 360) + 360) % 360;
      
      // 确保画笔在最终位置
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('lt', [deg]);
      }
    },

    // 移动到指定坐标（不绘图）
    moveTo: async function (xCoord, yCoord) {
      checkCancellation();
      
      // 如果速度10，直接移动到最终位置，跳过动画
      if (speedLevel >= 10) {
        x = xCoord;
        y = yCoord;
        ctx.moveTo(toCanvasX(x), toCanvasY(y)); // 只移动，不画线
        updatePenDisplay();
        
        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
          traceCollector.record('moveTo', [xCoord, yCoord]);
        }
        return this; // 支持链式调用
      }
      
      // 计算移动距离
      const deltaX = xCoord - x;
      const deltaY = yCoord - y;
      const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
      
      if (distance === 0) {
        // 如果已经在目标位置，直接返回
        updatePenDisplay();
        
        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
          traceCollector.record('moveTo', [xCoord, yCoord]);
        }
        return this;
      }
      
      // 渐进式移动：分步骤移动，使动画更流畅
      const steps = Math.max(1, Math.ceil(distance / 1)); // 每1像素一步，与fd/bk保持一致
      const stepSize = 1 / distance; // 每步的进度比例
      const totalDelay = getDelayTime();
      const stepDelay = steps > 1 ? totalDelay / (steps - 1) : 0; // 优化延时分配
      
      for (let i = 1; i <= steps; i++) {
        checkCancellation();
        
        // 计算当前步骤的位置
        const progress = stepSize * i;
        const currentX = x + deltaX * progress;
        const currentY = y + deltaY * progress;
        
        // 更新画笔位置显示（不绘制线条）
        ctx.moveTo(toCanvasX(currentX), toCanvasY(currentY));
        updatePenDisplay(currentX, currentY, angle);
        
        // 等待延时（除了最后一步）
        if (i < steps) {
          await sleep(stepDelay);
        }
      }
      
      // 更新最终位置
      x = xCoord;
      y = yCoord;
      ctx.moveTo(toCanvasX(x), toCanvasY(y));
      
      // 确保画笔在最终位置
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('moveTo', [xCoord, yCoord]);
      }

      return this; // 支持链式调用
    },

    // 连线到指定坐标（绘图）
    lineTo: function (xCoord, yCoord) {
      if (isPenDown) {
        ctx.lineTo(toCanvasX(xCoord), toCanvasY(yCoord));
        ctx.stroke();
        ctx.beginPath();
        ctx.moveTo(toCanvasX(xCoord), toCanvasY(yCoord));
      } else {
        ctx.moveTo(toCanvasX(xCoord), toCanvasY(yCoord));
      }
      x = xCoord;
      y = yCoord;
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('lineTo', [xCoord, yCoord]);
      }

      return this; // 支持链式调用
    },

    //线宽
    size: function (width) {
      lineWidth = width;
      ctx.lineWidth = lineWidth;
      ctx.lineJoin = 'round';     // 保持线条连接为圆角
      ctx.lineCap = 'round';      // 保持线条端点为圆角
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('size', [width]);
      }
    },

    //速度
    speed: function (v) {
      // 确保速度在1-10范围内
      const oldSpeedLevel = speedLevel;
      speedLevel = Math.max(1, Math.min(10, v));
      
      // 同步更新全局速度变量，确保下拉框显示一致
      window.__gocSpeedLevel = speedLevel;
      
      // 计算新的延时时间
      const newDelay = getDelayTime();
      const speedMap = {
        1: 5000, 2: 3500, 3: 2000, 4: 1000, 5: 300, 6: 30, 7: 15, 8: 5, 9: 2
      };
      const oldDelay = oldSpeedLevel >= 10 ? 0 : (speedMap[oldSpeedLevel] || 300);
      
      // 获取速度描述
      const getSpeedDescription = (level) => {
        if (level >= 10) return '瞬间'; // 0ms延时，瞬间执行
        if (level >= 9) return '极快';  // 2ms延时
        if (level >= 8) return '很快';  // 5ms延时
        if (level >= 7) return '快';    // 15ms延时
        if (level >= 6) return '较快';  // 30ms延时
        if (level >= 5) return '中等';  // 300ms延时
        if (level >= 3) return '慢';    // 1000-2000ms延时
        return '极慢';                  // 3500-5000ms延时
      };
      
      logger.log(`画笔速度已设置: 等级 ${speedLevel} (${getSpeedDescription(speedLevel)}) - 延时 ${newDelay}ms`);
      if (speedLevel !== oldSpeedLevel) {
        logger.log(`速度变化: ${oldSpeedLevel} → ${speedLevel}, 延时变化: ${oldDelay}ms → ${newDelay}ms`);
      }

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('speed', [v]);
      }
    },

    // 显示笔
    show: function () {
      if (setPenVisible) setPenVisible(true);
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('show', []);
      }
    },

    // 获取当前速度信息
    getSpeedInfo: function () {
      const delay = getDelayTime();
      const speedPercent = Math.round((1 - delay / 1000) * 100);
      const getSpeedDescription = (level) => {
        if (level >= 10) return '瞬间'; // 0ms延时，瞬间执行
        if (level >= 9) return '极快';  // 2ms延时
        if (level >= 8) return '很快';  // 5ms延时
        if (level >= 7) return '快';    // 15ms延时
        if (level >= 6) return '较快';  // 30ms延时
        if (level >= 5) return '中等';  // 300ms延时
        if (level >= 3) return '慢';    // 1000-2000ms延时
        return '极慢';                  // 3500-5000ms延时
      };
      
      return {
        level: speedLevel,
        delay: delay,
        speedPercent: speedPercent,
        description: getSpeedDescription(speedLevel)
      };
    },

    // 隐藏笔
    hide: function () {
      if (setPenVisible) setPenVisible(false);

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('hide', []);
      }
    },

    //颜色  
    c: function (color) {
      if (typeof color === "number") {
        ctx.strokeStyle = colorMap[color] || "black"; // 默认黑色
        ctx.fillStyle = colorMap[color] || "black"; // 默认黑色
      } else {
        //currentColor = color;
      }
      logger.log(color);
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('c', [color]);
      }
    },

    rgb: function (r, g, b) {
      // 找到当前最大的键
      const keys = Object.keys(colorMap).map(Number);
      const maxKey = keys.length > 0 ? Math.max(...keys) : 0;
      const newKey = maxKey + 1;
      const colorValue = `rgb(${r},${g},${b})`;
      // 添加到 colorMap
      colorMap[newKey] = colorValue;
      logger.log(colorMap);

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('rgb', [r, g, b], { newColorKey: newKey, colorValue: colorValue });
      }

      // 返回新的键
      return newKey;
    },


    // 加载图片
    picL: async function (...args) {
      logger.log("picL args:", args);
      logger.log("picL args type:", typeof args);
      logger.log("picL args length:", args.length)
      if (args.length === 2) {
        // 单张图片: pen.picL(id, fname)
        const [id, fname] = args;
        logger.log(`Loading image ${fname} with id ${id}`);
        try {
          checkCancellation();
          const img = await loadImage(fname);
          imageMap[id] = img;
          logger.log(`✓ Loaded image ${fname} with id ${id}, size: ${img.width}x${img.height}`);
        } catch (error) {
          logger.error(`✗ Error loading image ${fname}:`, error);
        }
      } else if (args.length === 3) {
        // 多张图片: pen.picL(idBegin, idEnd, fnames)
        const [idBegin, idEnd, fnames] = args;
        const fileNames = fnames.split(',');
        for (let i = 0; i <= idEnd - idBegin && i < fileNames.length; i++) {
          checkCancellation();
          const id = idBegin + i;
          const fname = fileNames[i].trim();
          try {
            const img = await loadImage(fname);
            imageMap[id] = img;
            logger.log(`✓ Loaded image ${fname} with id ${id}, size: ${img.width}x${img.height}`);
          } catch (error) {
            logger.error(`✗ Error loading image ${fname}:`, error);
          }
        }
      } else if (args.length === 4) {
        // 多张图片: pen.picL(idBegin, idEnd, fname, sBegin)
        const [idBegin, idEnd, fname, sBegin] = args;
        const baseName = fname.substring(0, fname.lastIndexOf('.'));
        const extension = fname.substring(fname.lastIndexOf('.'));

        for (let i = 0; i <= idEnd - idBegin; i++) {
          checkCancellation();
          const id = idBegin + i;
          const fileNumber = sBegin + i;
          const fullFname = `${baseName}${fileNumber}${extension}`;
          try {
            const img = await loadImage(fullFname);
            imageMap[id] = img;
            logger.log(`✓ Loaded image ${fullFname} with id ${id}, size: ${img.width}x${img.height}`);
          } catch (error) {
            logger.error(`✗ Error loading image ${fullFname}:`, error);
          }
        }
      }

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('picL', args, { imageCount: Object.keys(imageMap).length });
      }

      //return this; // 支持链式调用
    },


    // 显示图片    
    pic: function (...args) {
      if (args.length === 1) {
        // pen.pic(id) - 在笔位置显示图片，使用原始大小
        const [id] = args;
        const img = imageMap[id];
        if (img && img.complete) {
          // 保存当前状态
          ctx.save();
          // 移动到笔位置，图片中心对齐
          ctx.translate(toCanvasX(x), toCanvasY(y));
          // 根据picAlwaysUp设置决定是否旋转
          if (!picAlwaysUp) {
            // 根据当前角度旋转（新角度系统：角度0向上，逆时针为正）
            // 画布坐标顺时针为正，所以需要调整角度
            ctx.rotate((angle) * Math.PI / 180);
          }
          // 绘制图片，中心对齐
          ctx.drawImage(img, -img.width / 2, -img.height / 2);
          // 恢复状态
          ctx.restore();
          logger.log(`Displayed image ${id} at (${x}, ${y}) with size ${img.width}x${img.height}, alwaysUp: ${picAlwaysUp}`);
        } else if (img) {
          logger.error(`Image with id ${id} is not fully loaded yet`);
        } else {
          logger.error(`Image with id ${id} not found in imageMap:`, Object.keys(imageMap));
        }
      } else if (args.length === 3) {
        // pen.pic(id, w, h) - 指定宽度和高度
        const [id, w, h] = args;
        const img = imageMap[id];
        if (img && img.complete) {
          ctx.save();
          ctx.translate(toCanvasX(x), toCanvasY(y));
          // 根据picAlwaysUp设置决定是否旋转
          if (!picAlwaysUp) {
            ctx.rotate((angle) * Math.PI / 180);
          }
          // 绘制图片，指定大小，中心对齐
          ctx.drawImage(img, -w / 2, -h / 2, w, h);
          ctx.restore();
          logger.log(`Displayed image ${id} at (${x}, ${y}) with size ${w}x${h}, alwaysUp: ${picAlwaysUp}`);
        } else if (img) {
          logger.error(`Image with id ${id} is not fully loaded yet`);
        } else {
          logger.error(`Image with id ${id} not found in imageMap:`, Object.keys(imageMap));
        }
      } else if (args.length === 7) {
        // pen.pic(cav, id, w, h, angle, x, y) - 增强格式
        const [cav, id, w, h, imgAngle, imgX, imgY] = args;
        const img = imageMap[id];
        if (img && img.complete) {
          ctx.save();
          ctx.translate(toCanvasX(imgX), toCanvasY(imgY));
          // 增强格式总是使用指定的角度，不受picAlwaysUp影响
          ctx.rotate((-imgAngle) * Math.PI / 180);
          // 绘制图片，指定大小，中心对齐
          ctx.drawImage(img, -w / 2, -h / 2, w, h);
          ctx.restore();
          logger.log(`Displayed image ${id} at (${imgX}, ${imgY}) with size ${w}x${h} and angle ${imgAngle}`);
        } else if (img) {
          logger.error(`Image with id ${id} is not fully loaded yet`);
        } else {
          logger.error(`Image with id ${id} not found in imageMap:`, Object.keys(imageMap));
        }
      }

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('pic', args, { imageDisplayed: args.length > 0 ? args[0] : null });
      }

      //return this; // 支持链式调用
    },

    //空心圆 o（半径，颜色）
    o: function (r, color) {
      // 检查参数数量
      const args = Array.from(arguments);
      if (args.length > 2) {
        throw new Error(`错误：命令 'pen.o' 最多接受 2 个参数，但提供了 ${args.length} 个参数。请检查参数数量是否正确。`);
      }
      
      // 检查必需参数
      if (r === undefined || r === null || isNaN(r)) {
        throw new Error(`错误：没有提供参数。`);
      }
      
      // 如果传入了颜色参数，使用传入的颜色；否则使用当前画笔颜色
      if (color !== undefined) {
        ctx.strokeStyle = colorMap[color] || "black";
      }
      // 如果没有传入颜色参数，保持当前的 ctx.strokeStyle（由 pen.c() 设置）

      radius = r;

      // 保存当前状态
      ctx.save();
      // 移动到笔位置
      ctx.translate(toCanvasX(x), toCanvasY(y));
      // 根据picAlwaysUp设置决定是否旋转
      if (!picAlwaysUp) {
        // 根据当前角度旋转（画布坐标顺时针为正，这里用 -angle 保持与逻辑角度一致）
        ctx.rotate((angle) * Math.PI / 180);
      }

      ctx.beginPath();
      ctx.arc(0, 0, radius, 0, Math.PI * 2);
      ctx.stroke();

      // 恢复状态
      ctx.restore();

      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown, picAlwaysUp });
        traceCollector.record('o', [r, color], { shape: { type: 'circle', radius: r, filled: false } });
      }
    },

    //实心圆 oo（半径，颜色）
    oo: function (r, color) {
      // 检查参数数量
      const args = Array.from(arguments);
      if (args.length > 2) {
        throw new Error(`错误：命令 'pen.oo' 最多接受 2 个参数，但提供了 ${args.length} 个参数。请检查参数数量是否正确。`);
      }
      
      // 检查必需参数
      if (r === undefined || r === null || isNaN(r)) {
        throw new Error(`错误：没有提供参数。`);
      }
      
      // 保存当前的填充颜色
      const originalFillStyle = ctx.fillStyle;
      
      // 如果传入了颜色参数，使用传入的颜色；否则使用当前画笔颜色
      if (color !== undefined) {
        ctx.fillStyle = colorMap[color] || "black";
      }
      // 如果没有传入颜色参数，保持当前的 ctx.fillStyle（由 pen.c() 设置）

      radius = r;

      // 保存当前状态
      ctx.save();
      // 移动到笔位置
      ctx.translate(toCanvasX(x), toCanvasY(y));
      // 根据picAlwaysUp设置决定是否旋转
      if (!picAlwaysUp) {
        // 根据当前角度旋转（画布坐标顺时针为正，这里用 -angle 保持与逻辑角度一致）
        ctx.rotate((angle) * Math.PI / 180);
      }

      ctx.beginPath();
      ctx.arc(0, 0, radius, 0, Math.PI * 2);
      ctx.fill();

      // 恢复状态
      ctx.restore();
      
      // 恢复原来的填充颜色
      ctx.fillStyle = originalFillStyle;

      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.fillStyle || 'black', lineWidth, isPenDown, picAlwaysUp });
        traceCollector.record('oo', [r, color], { shape: { type: 'circle', radius: r, filled: true } });
      }
    },

    //空心椭圆  e（水平半径，垂直半径）
    e: function (rX, rY, color) {
      // 检查参数数量
      const args = Array.from(arguments);
      if (args.length > 3) {
        throw new Error(`错误：命令 'pen.e' 最多接受 3 个参数，但提供了 ${args.length} 个参数。请检查参数数量是否正确。`);
      }
      
      // 检查必需参数
      if (rX === undefined || rX === null || isNaN(rX) || rY === undefined || rY === null || isNaN(rY)) {
        throw new Error(`错误：没有提供参数。`);
      }
      
      // 如果传入了颜色参数，使用传入的颜色；否则使用当前画笔颜色
      if (color !== undefined) {
        ctx.strokeStyle = colorMap[color] || "black";
      }
      // 如果没有传入颜色参数，保持当前的 ctx.strokeStyle（由 pen.c() 设置）

      radiusX = rX;
      radiusY = rY;

      // 保存当前状态
      ctx.save();
      // 移动到笔位置
      ctx.translate(toCanvasX(x), toCanvasY(y));
      // 根据picAlwaysUp设置决定是否旋转
      if (!picAlwaysUp) {
        // 根据当前角度旋转（画布坐标顺时针为正，这里用 -angle 保持与逻辑角度一致）
        ctx.rotate((angle) * Math.PI / 180);
      }

      ctx.beginPath();
      ctx.ellipse(0, 0, radiusX, radiusY, 0, 0, Math.PI * 2);
      ctx.stroke();

      // 恢复状态
      ctx.restore();

      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('e', [rX, rY, color], { shape: { type: 'ellipse', radiusX: rX, radiusY: rY, filled: false } });
      }
    },

    //实心椭圆
    ee: function (rX, rY, color) {
      // 检查参数数量
      const args = Array.from(arguments);
      if (args.length > 3) {
        throw new Error(`错误：命令 'pen.ee' 最多接受 3 个参数，但提供了 ${args.length} 个参数。请检查参数数量是否正确。`);
      }
      
      // 保存当前的填充颜色
      const originalFillStyle = ctx.fillStyle;
      
      // 如果传入了颜色参数，使用传入的颜色；否则使用画笔默认颜色（蓝色）
      if (color !== undefined) {
        ctx.fillStyle = colorMap[color] || "black";
      } else {
        // 如果没有传入颜色参数，使用画笔默认颜色（蓝色）
        ctx.fillStyle = colorMap[2] || "blue";
      }

      radiusX = rX;
      radiusY = rY;

      // 保存当前状态
      ctx.save();
      // 移动到笔位置
      ctx.translate(toCanvasX(x), toCanvasY(y));
      // 根据picAlwaysUp设置决定是否旋转
      if (!picAlwaysUp) {
        // 根据当前角度旋转（画布坐标顺时针为正，这里用 -angle 保持与逻辑角度一致）
        ctx.rotate((angle) * Math.PI / 180);
      }

      ctx.beginPath();
      ctx.ellipse(0, 0, radiusX, radiusY, 0, 0, Math.PI * 2);
      ctx.fill();

      // 恢复状态
      ctx.restore();
      
      // 恢复原来的填充颜色
      ctx.fillStyle = originalFillStyle;

      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.fillStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('ee', [rX, rY, color], { shape: { type: 'ellipse', radiusX: rX, radiusY: rY, filled: true } });
      }
    },

    // 空心长方形
    r: function (w, h, color) {
      // 检查参数数量
      const args = Array.from(arguments);
      if (args.length > 3) {
        throw new Error(`错误：命令 'pen.r' 最多接受 3 个参数，但提供了 ${args.length} 个参数。请检查参数数量是否正确。`);
      }
      
      // 检查必需参数
      if (w === undefined || w === null || isNaN(w) || h === undefined || h === null || isNaN(h)) {
        throw new Error(`错误：没有提供参数。`);
      }
      
      // 如果传入了颜色参数，使用传入的颜色；否则使用当前画笔颜色
      if (color !== undefined) {
        ctx.strokeStyle = colorMap[color] || "black";
      }
      // 如果没有传入颜色参数，保持当前的 ctx.strokeStyle（由 pen.c() 设置）

      width = w;
      height = h;

      // 保存当前状态
      ctx.save();
      // 移动到笔位置
      ctx.translate(toCanvasX(x), toCanvasY(y));
      // 根据picAlwaysUp设置决定是否旋转
      if (!picAlwaysUp) {
        // 根据当前角度旋转（画布坐标顺时针为正，这里用 -angle 保持与逻辑角度一致）
        ctx.rotate((angle) * Math.PI / 180);
      }

      // 从中心开始绘制矩形，所以需要调整起始位置到左上角
      const startX = -width / 2;
      const startY = -height / 2;  // 在旋转后的坐标系中，左上角Y值更小
      ctx.strokeRect(startX, startY, width, height);

      // 恢复状态
      ctx.restore();

      // 画笔保持在中心位置
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('r', [w, h, color], { shape: { type: 'rectangle', width: w, height: h, filled: false } });
      }
    },

    // 实心长方形
    rr: function (w, h, color) {
      // 检查参数数量
      const args = Array.from(arguments);
      if (args.length > 3) {
        throw new Error(`错误：命令 'pen.rr' 最多接受 3 个参数，但提供了 ${args.length} 个参数。请检查参数数量是否正确。`);
      }
      
      // 检查必需参数
      if (w === undefined || w === null || isNaN(w) || h === undefined || h === null || isNaN(h)) {
        throw new Error(`错误：没有提供参数。`);
      }
      
      // 保存当前的填充颜色
      const originalFillStyle = ctx.fillStyle;
      
      // 如果传入了颜色参数，使用传入的颜色；否则使用画笔默认颜色（蓝色）
      if (color !== undefined) {
        ctx.fillStyle = colorMap[color] || "black";
      } else {
        // 如果没有传入颜色参数，使用画笔默认颜色（蓝色）
        ctx.fillStyle = colorMap[2] || "blue";
      }

      width = w;
      height = h;

      // 保存当前状态
      ctx.save();
      // 移动到笔位置
      ctx.translate(toCanvasX(x), toCanvasY(y));
      // 根据picAlwaysUp设置决定是否旋转
      if (!picAlwaysUp) {
        // 根据当前角度旋转（画布坐标顺时针为正，这里用 -angle 保持与逻辑角度一致）
        ctx.rotate((angle) * Math.PI / 180);
      }

      // 从中心开始绘制矩形，所以需要调整起始位置到左上角
      const startX = -width / 2;
      const startY = -height / 2;  // 在旋转后的坐标系中，左上角Y值更小
      ctx.fillRect(startX, startY, width, height);

      // 恢复状态
      ctx.restore();
      
      // 恢复原来的填充颜色
      ctx.fillStyle = originalFillStyle;

      // 画笔保持在中心位置
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.fillStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('rr', [w, h, color], { shape: { type: 'rectangle', width: w, height: h, filled: true } });
      }
    },

    // 显示网格线坐标
    showXY: function (len, color, size) {
      // 保存当前画笔状态和路径
      ctx.save();

      // 设置网格线颜色和粗细
      ctx.strokeStyle = colorMap[color] || "black";
      ctx.lineWidth = size || 1;
      ctx.lineJoin = 'round';     // 设置网格线连接为圆角
      ctx.lineCap = 'round';      // 设置网格线端点为圆角

      // 获取画布尺寸
      const canvasWidth = ctx.canvas.width;
      const canvasHeight = ctx.canvas.height;

      // 计算中心点
      const centerX = canvasWidth / 2;
      const centerY = canvasHeight / 2;

      // 完全独立地开始一个新的路径来绘制网格
      ctx.beginPath();

      // 绘制水平网格线
      // 从中心点开始，向上绘制水平网格线
      for (let yLine = centerY; yLine >= 0; yLine -= len) {
        ctx.moveTo(0, yLine);
        ctx.lineTo(canvasWidth, yLine);
      }
      // 从中心点开始，向下绘制水平网格线
      for (let yLine = centerY + len; yLine <= canvasHeight; yLine += len) {
        ctx.moveTo(0, yLine);
        ctx.lineTo(canvasWidth, yLine);
      }

      // 绘制垂直网格线
      // 从中心点开始，向左绘制垂直网格线
      for (let xLine = centerX; xLine >= 0; xLine -= len) {
        ctx.moveTo(xLine, 0);
        ctx.lineTo(xLine, canvasHeight);
      }
      // 从中心点开始，向右绘制垂直网格线
      for (let xLine = centerX + len; xLine <= canvasWidth; xLine += len) {
        ctx.moveTo(xLine, 0);
        ctx.lineTo(xLine, canvasHeight);
      }

      // 描边网格线
      ctx.stroke();

      // 恢复画笔状态和路径
      ctx.restore();

      // 确保恢复绘图状态
      if (isPenDown) {
        ctx.beginPath();
        ctx.moveTo(toCanvasX(x), toCanvasY(y));
      }

      logger.log(`Displayed grid with interval ${len}, color ${color}, line width ${size}`);

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('showXY', [len, color, size], { gridInterval: len, gridColor: colorMap[color] || 'black', gridLineWidth: size || 1 });
      }
    },

    //清屏
    cls: function () {
      ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
      
      // 重置画笔位置到原点
      x = 0;
      y = 0;
      angle = 0;
      ctx.beginPath();
      ctx.moveTo(toCanvasX(x), toCanvasY(y));
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('cls', [], { canvasWidth: ctx.canvas.width, canvasHeight: ctx.canvas.height });
      }
    },

    // 扩展：绘制文本，居中于当前笔位置
    text: function (value, colorIndex, size) { // 添加size参数
      const isNumber = typeof value === 'number' && !Number.isNaN(value);
      // 数字格式化：按 floatPrecision 四舍五入，但不补零
      function formatNumber(num, p) {
        if (!Number.isFinite(num)) return String(num);
        if (typeof p !== 'number' || p < 0) return String(num);
        const fixed = num.toFixed(Math.floor(p));
        // 去除多余的尾部 0 和小数点
        return fixed.replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.0+$/, '').replace(/\.$/, '');
      }
      const text = isNumber ? formatNumber(value, floatPrecision) : String(value);
      const fill = (typeof colorIndex === 'number') ? (colorMap[colorIndex] || 'black') : (ctx.fillStyle || ctx.strokeStyle || 'black');

      // 字体大小优先级：size参数 > textFontSize设置 > 默认计算
      let fontSize;
      if (typeof size === 'number' && size > 0) {
        fontSize = size;
      } else if (typeof textFontSize === 'number' && textFontSize > 0) {
        fontSize = textFontSize;
      } else {
        fontSize = Math.max(10, 8 + lineWidth * 2);
      }
      ctx.save();
      // 应用文本方向：始终向上或随笔方向
      if (!textAlwaysUp) {
        ctx.translate(toCanvasX(x), toCanvasY(y));
        ctx.rotate((angle) * Math.PI / 180);
        ctx.translate(-toCanvasX(x), -toCanvasY(y));
      }
      ctx.fillStyle = fill;
      ctx.font = `${fontSize}px ${textFontFamily}`;
      ctx.textAlign = 'center';
      ctx.textBaseline = 'middle';
      ctx.fillText(text, toCanvasX(x), toCanvasY(y));
      ctx.restore();
      updatePenDisplay();

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: fill, lineWidth, isPenDown, textPrecision: floatPrecision, textFontSize: fontSize, textFontFamily, picAlwaysUp });
        traceCollector.record('text', [value, colorIndex, size], {
          text: text,
          fontSize: fontSize,
          fontFamily: textFontFamily,
          textAlwaysUp: textAlwaysUp
        });
      }
    },

    // 设置浮点数精度（不补零，仅限制最多小数位的显示精度）
    setprecision: function (len) {
      const n = Math.max(0, Math.min(10, Math.floor(Number(len))))
      if (Number.isFinite(n)) {
        floatPrecision = n;

        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown, textPrecision: floatPrecision });
          traceCollector.record('setprecision', [len], { precision: floatPrecision });
        }
      }
    },

    // 设置文本字号（像素）
    textSize: function (i) {
      const n = Number(i);
      if (Number.isFinite(n) && n > 0) {
        textFontSize = n;

        // 记录Trace
        if (traceCollector) {
          traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown, textFontSize: textFontSize });
          traceCollector.record('textSize', [i], { fontSize: textFontSize });
        }
      }
    },

    // 设置文本方向：1=始终向上，0=随笔方向旋转
    textU: function (orientation) {
      textAlwaysUp = !!orientation;

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown, textAlwaysUp: textAlwaysUp });
        traceCollector.record('textU', [orientation], { textAlwaysUp: textAlwaysUp });
      }
    },

    // 设置图片方向：1=始终向上，0=随笔方向旋转
    picU: function (orientation) {
      picAlwaysUp = !!orientation;
      logger.log(`Picture orientation set to: ${picAlwaysUp ? 'always up' : 'follow pen direction'}`);
    },

    // 设置文本字体：支持字体编号或字体名称
    font: function (f) {
      if (typeof f === 'number') {
        // 字体编号映射（根据附录1）
        const fontMap = {
          0: 'Arial',
          1: 'Times New Roman',
          2: '微软雅黑',
          3: '仿宋',
          4: '宋体',
          5: '黑体',
          6: '楷体',
          7: '细明体',
          8: '幼圆',
          9: '隶书',
          10: '华文细黑',
          11: '华文楷体',
          12: '华文宋体',
          13: '华文中宋',
          14: '华文仿宋',
          15: '方正舒体',
          16: '方正姚体',
          17: '华文彩云',
          18: '华文琥珀',
          19: '华文隶书',
          20: '华文行楷',
          21: '华文新魏'
        };
        textFontFamily = fontMap[f] || 'sans-serif';
      } else if (typeof f === 'string') {
        // 直接使用字体名称
        textFontFamily = f;
      }

      // 记录Trace
      if (traceCollector) {
        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown, textFontFamily: textFontFamily });
        traceCollector.record('font', [f], { fontFamily: textFontFamily });
      }
    },
  };

  // 🔥 新增：扩展trace记录方法
  pen.recordControlFlow = function (type, condition) {
    logger.log(`🔄 记录控制流: ${type} - ${condition}`);
    if (traceCollector) {
      traceCollector.recordControlFlow(type, condition);
    }
  };

  pen.recordIO = function (type, content) {
    logger.log(`📝 记录IO操作: ${type} - ${content}`);
    if (traceCollector) {
      traceCollector.recordIO(type, content);
    }
  };

  pen.recordSystem = function (type, ...args) {
    logger.log(`⚙️ 记录系统操作: ${type} - ${args.join(', ')}`);
    if (traceCollector) {
      traceCollector.recordSystem(type, args);
    }
  };

  pen.recordDeclaration = function (declarationType, fullDeclaration, dataType, name, size = null) {
    logger.log(`📋 记录声明: ${declarationType} - ${fullDeclaration}`);
    if (traceCollector) {
      traceCollector.recordDeclaration(declarationType, fullDeclaration, dataType, name, size);
    }
  };

  // 创建p对象作为pen的别名，用于简化代码
  const p = pen;

  // 根据速度等级获取延时时间
  function getDelayTime() {
    // 新的速度配置：速度1极慢，速度10瞬间显示图形
    // 速度1：5000ms，速度3：2000ms，速度5：300ms，速度7：100ms，速度10：瞬间显示
    if (speedLevel >= 10) return 0; // 最高速度设置为0ms（瞬间显示）
    
    // 自定义速度映射 - 大幅减少6-9速度延时，让绘画动画更快
    const speedMap = {
      1: 5000,  // 极慢
      2: 3500,  // 很慢
      3: 2000,  // 慢
      4: 1000,  // 较慢
      5: 300,   // 中等
      6: 30,    // 较快 (从100ms大幅减少到30ms)
      7: 15,    // 快 (从50ms大幅减少到15ms)
      8: 5,     // 很快 (从20ms大幅减少到5ms)
      9: 2      // 极快 (从5ms减少到2ms)
    };
    
    return speedMap[speedLevel] || 300; // 默认300ms
  }

  // 注册全局速度更新函数，供外部调用
  window.__gocUpdateSpeed = function(newSpeed) {
    const oldSpeedLevel = speedLevel;
    speedLevel = Math.max(1, Math.min(10, newSpeed));
    logger.log(`外部速度更新: ${oldSpeedLevel} → ${speedLevel}`);
  };

  //辅助延时函数
  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  // 取消检查函数
  function checkCancellation() {
    if (cancelToken && cancelToken.cancel) {
      throw new Error('CANCELLED');
    }
  }

  /* 
  * 解析tokens并计算表达式的值
  * 用于处理for循环中的复杂表达式
  */
  function evalTokens(tokens) {
    if (!tokens || tokens.length === 0) return 0;

    // 检查是否是数组访问：arr[index]
    if (tokens.length === 4 && tokens[1] === "[" && tokens[3] === "]") {
      const arrayName = tokens[0];
      const indexStr = tokens[2];
      
      // 计算索引
      let index;
      if (/^[a-zA-Z_]\w*$/.test(indexStr)) {
        // 变量引用
        if (!Object.prototype.hasOwnProperty.call(variables, indexStr)) {
          throw new Error(`错误：变量 '${indexStr}' 未定义。请先使用 'int ${indexStr};' 或 'int ${indexStr} = 初始值;' 声明变量。`);
        }
        index = Math.floor(parseFloat(variables[indexStr]));
      } else {
        // 直接数字
        index = Math.floor(parseFloat(indexStr));
      }
      
      // 访问数组元素
      if (arrays[arrayName] && index >= 0 && index < arrays[arrayName].length) {
        const value = arrays[arrayName][index];
        return value;
      } else {
        return 0;
      }
    }

    // 如果只有一个token，直接处理
    if (tokens.length === 1) {
      const token = tokens[0];
      // 检查是否是数字
      if (/^\d+(\.\d+)?$/.test(token)) {
        return parseFloat(token);
      }
      // 检查是否是变量
      if (/^[a-zA-Z_]\w*$/.test(token)) {
        if (!Object.prototype.hasOwnProperty.call(variables, token)) {
          throw new Error(`错误：变量 '${token}' 未定义。请先使用 'int ${token};' 或 'int ${token} = 初始值;' 声明变量。`);
        }
        return variables[token];
      }
      return 0;
    }

    // 检查表达式是否包含浮点数或浮点数变量
    const hasFloatLiteral = tokens.some(token => /^\d*\.\d+$/.test(token));
    const hasFloatVariable = tokens.some(token => {
      if (/^[a-zA-Z_]\w*$/.test(token) && Object.prototype.hasOwnProperty.call(variables, token)) {
        return typeof variables[token] === 'number' && !Number.isInteger(variables[token]);
      }
      return false;
    });

    // 如果包含浮点数，使用浮点数运算，否则使用整数运算
    if (hasFloatLiteral || hasFloatVariable) {
      return evalFloatExpression(tokens);
    } else {
      return evalSimpleExpression(tokens);
    }
  }

  /* 
  * 简化的表达式计算函数
  * 用于处理基本的算术运算，正确处理运算符优先级和整数除法
  */
  function evalSimpleExpression(tokens) {
    if (!tokens || tokens.length === 0) return 0;

    // 处理括号表达式 - 找到最外层的括号对
    for (let i = 0; i < tokens.length; i++) {
      if (tokens[i] === '(') {
        let depth = 1;
        let j = i + 1;
        while (j < tokens.length && depth > 0) {
          if (tokens[j] === '(') depth++;
          else if (tokens[j] === ')') depth--;
          j++;
        }
        if (depth === 0) {
          // 找到了匹配的右括号
          const leftPart = tokens.slice(0, i);
          const parenContent = tokens.slice(i + 1, j - 1);
          const rightPart = tokens.slice(j);
          
          // 计算括号内的值
          const parenValue = evalSimpleExpression(parenContent);
          
          // 如果括号是完整的表达式，直接返回括号内的值
          if (leftPart.length === 0 && rightPart.length === 0) {
            return parenValue;
          }
          
          // 否则，将括号内的值替换为数字，然后重新计算
          const newTokens = [...leftPart, parenValue.toString(), ...rightPart];
          return evalSimpleExpression(newTokens);
        }
      }
    }

    // 处理逻辑或运算（优先级最低）
    for (let i = tokens.length - 1; i >= 0; i--) {
      if (tokens[i] === '||') {
        const left = evalSimpleExpression(tokens.slice(0, i));
        const right = evalSimpleExpression(tokens.slice(i + 1));
        return left || right;
      }
    }

    // 处理逻辑与运算
    for (let i = tokens.length - 1; i >= 0; i--) {
      if (tokens[i] === '&&') {
        const left = evalSimpleExpression(tokens.slice(0, i));
        const right = evalSimpleExpression(tokens.slice(i + 1));
        return left && right;
      }
    }

    // 处理比较运算
    for (let i = tokens.length - 1; i >= 0; i--) {
      if (tokens[i] === '==' || tokens[i] === '!=' || tokens[i] === '<' || tokens[i] === '>' || tokens[i] === '<=' || tokens[i] === '>=') {
        const left = evalSimpleExpression(tokens.slice(0, i));
        const right = evalSimpleExpression(tokens.slice(i + 1));
        switch (tokens[i]) {
          case '==': return left == right ? 1 : 0;
          case '!=': return left != right ? 1 : 0;
          case '<': return left < right ? 1 : 0;
          case '>': return left > right ? 1 : 0;
          case '<=': return left <= right ? 1 : 0;
          case '>=': return left >= right ? 1 : 0;
        }
      }
    }

    // 处理加减运算（优先级低，从右到左处理）
    for (let i = tokens.length - 1; i >= 0; i--) {
      if (tokens[i] === '+' || tokens[i] === '-') {
        const left = evalSimpleExpression(tokens.slice(0, i));
        const right = evalSimpleExpression(tokens.slice(i + 1));
        if (tokens[i] === '+') {
          return Math.trunc(left + right); // 整数运算（向零取整）
        } else {
          return Math.trunc(left - right); // 整数运算（向零取整）
        }
      }
    }

    // 处理乘除模运算（优先级高，从右到左处理）
    for (let i = tokens.length - 1; i >= 0; i--) {
      if (tokens[i] === '*' || tokens[i] === '/' || tokens[i] === '%') {
        const left = evalSimpleExpression(tokens.slice(0, i));
        const right = evalSimpleExpression(tokens.slice(i + 1));
        if (tokens[i] === '*') {
          return Math.trunc(left * right); // 整数运算（向零取整）
        } else if (tokens[i] === '/') {
          // 整数除法：向零取整（C++标准）
          if (right !== 0) {
            return Math.trunc(left / right);
          } else {
            return 0;
          }
        } else if (tokens[i] === '%') {
          // 模运算：整数取模（C++标准）
          if (right !== 0) {
            return Math.trunc(left % right);
          } else {
            return 0;
          }
        }
      }
    }

    // 处理逻辑非运算（一元运算符）
    if (tokens.length === 2 && tokens[0] === '!') {
      const operand = evalSimpleExpression(tokens.slice(1));
      return !operand ? 1 : 0;
    }

    // 处理单个token
    if (tokens.length === 1) {
      const token = tokens[0];
      // 检查是否是数字
      if (/^\d+(\.\d+)?$/.test(token)) {
        return Math.trunc(parseFloat(token)); // 确保是整数
      }
      // 检查是否是变量
      if (/^[a-zA-Z_]\w*$/.test(token)) {
        if (!Object.prototype.hasOwnProperty.call(variables, token)) {
          throw new Error(`错误：变量 '${token}' 未定义。请先使用 'int ${token};' 或 'int ${token} = 初始值;' 声明变量。`);
        }
        return Math.trunc(variables[token]); // 确保是整数
      }
    }

    return 0;
  }

  /* 
  * 浮点数表达式计算函数
  * 用于处理包含浮点数的算术运算，保持浮点数精度
  */
  function evalFloatExpression(tokens) {
    if (!tokens || tokens.length === 0) return 0;

    // 处理括号表达式
    if (tokens[0] === '(' && tokens[tokens.length - 1] === ')') {
      return evalFloatExpression(tokens.slice(1, -1));
    }

    // 处理加减运算（优先级低，从右到左处理）
    for (let i = tokens.length - 1; i >= 0; i--) {
      if (tokens[i] === '+' || tokens[i] === '-') {
        const left = evalFloatExpression(tokens.slice(0, i));
        const right = evalFloatExpression(tokens.slice(i + 1));
        if (tokens[i] === '+') {
          return left + right; // 浮点数运算
        } else {
          return left - right; // 浮点数运算
        }
      }
    }

    // 处理乘除模运算（优先级高，从右到左处理）
    for (let i = tokens.length - 1; i >= 0; i--) {
      if (tokens[i] === '*' || tokens[i] === '/' || tokens[i] === '%') {
        const left = evalFloatExpression(tokens.slice(0, i));
        const right = evalFloatExpression(tokens.slice(i + 1));
        if (tokens[i] === '*') {
          return left * right; // 浮点数运算
        } else if (tokens[i] === '/') {
          // 浮点数除法：保持浮点数精度
          if (right !== 0) {
            return left / right;
          } else {
            return 0;
          }
        } else if (tokens[i] === '%') {
          // 浮点数模运算：保持浮点数精度
          if (right !== 0) {
            return left % right;
          } else {
            return 0;
          }
        }
      }
    }

    // 处理单个token
    if (tokens.length === 1) {
      const token = tokens[0];
      // 检查是否是数字（包括浮点数）
      if (/^\d+(\.\d+)?$/.test(token)) {
        return parseFloat(token); // 保持浮点数精度
      }
      // 检查是否是变量
      if (/^[a-zA-Z_]\w*$/.test(token)) {
        if (!Object.prototype.hasOwnProperty.call(variables, token)) {
          throw new Error(`错误：变量 '${token}' 未定义。请先使用 'int ${token};' 或 'int ${token} = 初始值;' 声明变量。`);
        }
        return parseFloat(variables[token]); // 转换为浮点数
      }
    }

    return 0;
  }

  /* 
  *计算表达式节点的值
  */
  function evalExpression(expr) {
    if (expr.type === "Literal") {
      // 检查是否是字符串字面量
      if (typeof expr.value === 'string' && expr.value.startsWith('"') && expr.value.endsWith('"')) {
        return expr.value.slice(1, -1); // 移除引号
      }
      return parseFloat(expr.value);
    }
    if (expr.type === "BinaryExpression") {
      const l = evalExpression(expr.left);
      const r = evalExpression(expr.right);
      
      // 检查是否是字符串连接操作
      if (expr.op === "+") {
        // 如果左右操作数中有字符串，则进行字符串连接
        if (typeof l === 'string' || typeof r === 'string') {
          return String(l) + String(r);
        }
        // 否则进行数字运算
        const leftStr = expr.left && expr.left.value ? expr.left.value.toString() : '';
        const rightStr = expr.right && expr.right.value ? expr.right.value.toString() : '';
        const hasFloat = leftStr.includes('.') || rightStr.includes('.');
        return hasFloat ? l + r : Math.trunc(l) + Math.trunc(r);
      }
      
      // 其他算术运算：检查是否包含浮点数，如果包含则使用浮点数运算
      const leftStr = expr.left && expr.left.value ? expr.left.value.toString() : '';
      const rightStr = expr.right && expr.right.value ? expr.right.value.toString() : '';
      const hasFloat = leftStr.includes('.') || rightStr.includes('.');
      switch (expr.op) {
        case "<": return l < r;
        case ">": return l > r;
        case "==": return l == r;
        case "!=": return l != r;
        case "<=": return l <= r;
        case ">=": return l >= r;
        case "-": return hasFloat ? l - r : Math.trunc(l) - Math.trunc(r);
        case "*": return hasFloat ? l * r : Math.trunc(l) * Math.trunc(r);
        case "/": return r !== 0 ? (hasFloat ? l / r : Math.trunc(Math.trunc(l) / Math.trunc(r))) : 0;
        case "%": return r !== 0 ? (hasFloat ? l % r : Math.trunc(l) % Math.trunc(r)) : 0;
        case "&&": return l && r;
        case "||": return l || r;
      }
    }
    if (expr.type === "UnaryExpression") {
      const operand = evalExpression(expr.operand);
      switch (expr.op) {
        case "+": return +operand;
        case "-": return -operand;
        case "!": return !operand;
      }
    }
    // 处理变量引用
    if (expr.type === "Identifier") {
      if (!Object.prototype.hasOwnProperty.call(variables, expr.name)) {
        throw new Error(`错误：变量 '${expr.name}' 未定义。请先使用 'int ${expr.name};' 或 'int ${expr.name} = 初始值;' 声明变量。`);
      }
      return variables[expr.name];
    }
    // 处理数组访问
    if (expr.type === "ArrayAccess") {
      const arrayName = expr.array;

      // 正确处理索引 - 支持复杂表达式
      let index;
      if (typeof expr.index === 'object') {
        // 复杂表达式，需要递归计算
        index = Math.floor(parseFloat(evalExpression(expr.index)));
      } else if (typeof expr.index === 'string' && /^[a-zA-Z_]\w*$/.test(expr.index)) {
        // 变量引用
        if (!Object.prototype.hasOwnProperty.call(variables, expr.index)) {
          throw new Error(`错误：变量 '${expr.index}' 未定义。请先使用 'int ${expr.index};' 或 'int ${expr.index} = 初始值;' 声明变量。`);
        }
        index = Math.floor(parseFloat(variables[expr.index]));
      } else {
        // 直接数字
        index = Math.floor(parseFloat(expr.index));
      }

      if (arrays[arrayName] && arrays[arrayName][index] !== undefined) {
        const value = arrays[arrayName][index];
        return value;
      }
      return 0;
    }
    return 0;
  }

  // 定义控制流异常类
  class BreakException extends Error {
    constructor() {
      super('Break statement');
      this.name = 'BreakException';
    }
  }

  class ContinueException extends Error {
    constructor() {
      super('Continue statement');
      this.name = 'ContinueException';
    }
  }

  /* 
  *异步函数 execStatement
  *用于执行一条语句 AST 节点（如代码块、for、if、表达式等）。
  */
  async function execStatement(stmt) {
    // 检查是否被取消
    checkCancellation();

    if (stmt.type === "BreakStatement") {
      // break 语句：抛出BreakException异常
      throw new BreakException();
    } else if (stmt.type === "ContinueStatement") {
      // continue 语句：抛出ContinueException异常
      throw new ContinueException();
    } else if (stmt.type === "BlockStatement") {
      //代码块（BlockStatement）
      for (const s of stmt.body) {
        checkCancellation();
        try {
          await execStatement(s);
        } catch (e) {
          // 如果是break或continue异常，继续向上抛出
          if (e instanceof BreakException || e instanceof ContinueException) {
            throw e;
          }
          // 其他异常也继续抛出
          throw e;
        }
      }
    } else if (stmt.type === "ForStatement") {
      //for 循环（ForStatement）
      logger.log("=== For循环执行调试 ===");
      logger.log("stmt.init:", stmt.init);
      logger.log("stmt.cond:", stmt.cond);
      logger.log("stmt.incr:", stmt.incr);

      const varName = stmt.init[1]; // 变量名在索引1：["int", "i", "=", "0"]

      // 处理初始化表达式 - 支持复杂表达式如 n/2+1
      let i;
      if (stmt.init.length > 3) {
        // 复杂初始化表达式，如 ["int", "i", "=", "n", "/", "2", "+", "1"]
        const initTokens = stmt.init.slice(3); // 获取等号后的所有tokens
        i = evalTokens(initTokens);
      } else {
        // 简单初始化表达式，如 ["int", "i", "=", "0"]
        i = parseFloat(stmt.init[3]);
      }

      // 将循环变量添加到全局变量表中
      variables[varName] = i;
      logger.log(`初始化: ${varName} = ${i}`);

      // 处理循环条件 - 支持复杂表达式如 i<=2*n
      let conditionResult = true;
      if (stmt.cond.length === 0) {
        // 空条件，表示无限循环（如 for(;;) 或 for(int i=0;;i++)）
        conditionResult = true;
        logger.log("条件: 空条件，无限循环");
      } else if (stmt.cond.length > 2) {
        // 复杂条件表达式，如 ["i", "<=", "2", "*", "n"]
        const condTokens = stmt.cond;

        // 查找比较操作符
        let opIndex = -1;
        let op = "";
        for (let j = 0; j < condTokens.length; j++) {
          if (["<", ">", "<=", ">=", "==", "!="].includes(condTokens[j])) {
            opIndex = j;
            op = condTokens[j];
            break;
          }
        }

        if (opIndex > 0 && opIndex < condTokens.length - 1) {
          // 分离左右操作数
          const leftTokens = condTokens.slice(0, opIndex);
          const rightTokens = condTokens.slice(opIndex + 1);

          const leftValue = evalTokens(leftTokens);
          const rightValue = evalTokens(rightTokens);

          // 执行比较
          switch (op) {
            case "<": conditionResult = leftValue < rightValue; break;
            case ">": conditionResult = leftValue > rightValue; break;
            case "<=": conditionResult = leftValue <= rightValue; break;
            case ">=": conditionResult = leftValue >= rightValue; break;
            case "==": conditionResult = leftValue == rightValue; break;
            case "!=": conditionResult = leftValue != rightValue; break;
            default: conditionResult = true;
          }
          logger.log(`条件: ${leftValue} ${op} ${rightValue} = ${conditionResult}`);
        } else {
          // 如果没有找到比较操作符，将整个表达式作为布尔值
          conditionResult = !!evalTokens(condTokens);
        }
      } else {
        // 简单条件表达式，如 ["i", "<=", "n"]
        let rightValue;
        if (typeof stmt.cond[2] === 'string' && /^[a-zA-Z_]\w*$/.test(stmt.cond[2])) {
          // 变量引用
          if (!Object.prototype.hasOwnProperty.call(variables, stmt.cond[2])) {
            throw new Error(`错误：变量 '${stmt.cond[2]}' 未定义。请先使用 'int ${stmt.cond[2]};' 或 'int ${stmt.cond[2]} = 初始值;' 声明变量。`);
          }
          rightValue = variables[stmt.cond[2]].toString();
        } else {
          // 直接数字
          rightValue = stmt.cond[2];
        }
        conditionResult = evalExpression({ type: "BinaryExpression", op: stmt.cond[1], left: { type: "Literal", value: i.toString() }, right: { type: "Literal", value: rightValue } });
      }

      // 执行循环
      while (conditionResult) {
        checkCancellation();
        try {
          for (const s of stmt.body) {
            checkCancellation();
            try {
              await execStatement(s);
            } catch (e) {
              // 如果是continue异常，跳过本次循环的剩余部分，继续下一次迭代
              if (e instanceof ContinueException) {
                break; // 跳出循环体，继续执行增量操作
              }
              // 如果是break异常，向上抛出，退出整个循环
              if (e instanceof BreakException) {
                throw e;
              }
              // 其他异常继续抛出
              throw e;
            }
          }
        } catch (e) {
          // 如果是break异常，退出整个while循环
          if (e instanceof BreakException) {
            break;
          }
          // 其他异常继续抛出
          throw e;
        }

        // 处理循环增量 - 支持各种算术运算
        if (stmt.incr.length === 2 && stmt.incr[1] === "++") {
          // i++
          variables[varName] = (variables[varName] || 0) + 1;
        } else if (stmt.incr.length === 2 && stmt.incr[0] === "++") {
          // ++i
          variables[varName] = (variables[varName] || 0) + 1;
        } else if (stmt.incr.length === 2 && stmt.incr[1] === "--") {
          // i--
          variables[varName] = (variables[varName] || 0) - 1;
        } else if (stmt.incr.length === 2 && stmt.incr[0] === "--") {
          // --i
          variables[varName] = (variables[varName] || 0) - 1;
        } else if (stmt.incr.length >= 3 && stmt.incr[1] === "=") {
          // 处理赋值表达式：a = a + 1, a = a - 2, a = a * 3, a = a / 2 等
          const assignmentTokens = stmt.incr.slice(2); // 获取等号后的表达式
          const newValue = evalTokens(assignmentTokens);
          variables[varName] = newValue;
          logger.log(`循环增量赋值: ${varName} = ${newValue}`);
        } else if (stmt.incr.length >= 3 && stmt.incr[1] === "+" && stmt.incr[2] === "=") {
          // 处理复合赋值：a += 1, a += 2 等
          const incrementTokens = stmt.incr.slice(3); // 获取+=后的值
          const incrementValue = evalTokens(incrementTokens);
          variables[varName] = (variables[varName] || 0) + incrementValue;
          logger.log(`循环增量复合加: ${varName} += ${incrementValue}, 结果: ${variables[varName]}`);
        } else if (stmt.incr.length >= 3 && stmt.incr[1] === "-" && stmt.incr[2] === "=") {
          // 处理复合赋值：a -= 1, a -= 2 等
          const decrementTokens = stmt.incr.slice(3); // 获取-=后的值
          const decrementValue = evalTokens(decrementTokens);
          variables[varName] = (variables[varName] || 0) - decrementValue;
          logger.log(`循环增量复合减: ${varName} -= ${decrementValue}, 结果: ${variables[varName]}`);
        } else if (stmt.incr.length >= 3 && stmt.incr[1] === "*" && stmt.incr[2] === "=") {
          // 处理复合赋值：a *= 2, a *= 3 等
          const multiplyTokens = stmt.incr.slice(3); // 获取*=后的值
          const multiplyValue = evalTokens(multiplyTokens);
          variables[varName] = (variables[varName] || 0) * multiplyValue;
          logger.log(`循环增量复合乘: ${varName} *= ${multiplyValue}, 结果: ${variables[varName]}`);
        } else if (stmt.incr.length >= 3 && stmt.incr[1] === "/" && stmt.incr[2] === "=") {
          // 处理复合赋值：a /= 2, a /= 3 等
          const divideTokens = stmt.incr.slice(3); // 获取/=后的值
          const divideValue = evalTokens(divideTokens);
          if (divideValue !== 0) {
            variables[varName] = Math.trunc((variables[varName] || 0) / divideValue);
          }
          logger.log(`循环增量复合除: ${varName} /= ${divideValue}, 结果: ${variables[varName]}`);
        } else {
          // 默认增量
          variables[varName] = (variables[varName] || 0) + 1;
        }

        i = variables[varName];
        logger.log(`增量后: ${varName} = ${i}`);

        // 重新计算循环条件
        if (stmt.cond.length === 0) {
          // 空条件，表示无限循环（如 for(;;) 或 for(int i=0;;i++)）
          conditionResult = true;
        } else if (stmt.cond.length > 2) {
          // 复杂条件表达式
          const condTokens = stmt.cond;

          // 查找比较操作符
          let opIndex = -1;
          let op = "";
          for (let j = 0; j < condTokens.length; j++) {
            if (["<", ">", "<=", ">=", "==", "!="].includes(condTokens[j])) {
              opIndex = j;
              op = condTokens[j];
              break;
            }
          }

          if (opIndex > 0 && opIndex < condTokens.length - 1) {
            // 分离左右操作数
            const leftTokens = condTokens.slice(0, opIndex);
            const rightTokens = condTokens.slice(opIndex + 1);

            const leftValue = evalTokens(leftTokens);
            const rightValue = evalTokens(rightTokens);

            // 执行比较
            switch (op) {
              case "<": conditionResult = leftValue < rightValue; break;
              case ">": conditionResult = leftValue > rightValue; break;
              case "<=": conditionResult = leftValue <= rightValue; break;
              case ">=": conditionResult = leftValue >= rightValue; break;
              case "==": conditionResult = leftValue == rightValue; break;
              case "!=": conditionResult = leftValue != rightValue; break;
              default: conditionResult = true;
            }
          } else {
            // 如果没有找到比较操作符，将整个表达式作为布尔值
            conditionResult = !!evalTokens(condTokens);
          }
        } else {
          // 简单条件表达式
          let rightValue;
          if (typeof stmt.cond[2] === 'string' && /^[a-zA-Z_]\w*$/.test(stmt.cond[2])) {
            // 变量引用
            rightValue = (variables[stmt.cond[2]] || 0).toString();
          } else {
            // 直接数字
            rightValue = stmt.cond[2];
          }
          conditionResult = evalExpression({ type: "BinaryExpression", op: stmt.cond[1], left: { type: "Literal", value: i.toString() }, right: { type: "Literal", value: rightValue } });
        }
      }
    } else if (stmt.type === "IfStatement") {
      //if 语句（IfStatement）
      logger.log("=== If语句执行调试 ===");
      logger.log("stmt.condition:", stmt.condition);
      logger.log("stmt.body:", stmt.body);
      logger.log("stmt.elseBody:", stmt.elseBody);

      const conditionResult = evalExpression(stmt.condition);
      logger.log("条件评估结果:", conditionResult);

      if (conditionResult) {
        logger.log("条件为真，执行if体");
        for (const s of stmt.body) {
          checkCancellation();
          try {
            await execStatement(s);
          } catch (e) {
            // 如果是break或continue异常，继续向上抛出
            if (e instanceof BreakException || e instanceof ContinueException) {
              throw e;
            }
            // 其他异常继续抛出
            throw e;
          }
        }
      } else if (stmt.elseBody) {
        logger.log("条件为假，执行else体");
        for (const s of stmt.elseBody) {
          checkCancellation();
          try {
            await execStatement(s);
          } catch (e) {
            // 如果是break或continue异常，继续向上抛出
            if (e instanceof BreakException || e instanceof ContinueException) {
              throw e;
            }
            // 其他异常继续抛出
            throw e;
          }
        }
      } else {
        logger.log("条件为假，无else体");
      }
    } else if (stmt.type === "WaitStatement") {
      // 执行 wait 语句
      const seconds = evalExpression(stmt.value);
      if (seconds >= 0) {
        // 将等待时间分解为小段，以便能够响应取消
        const totalMs = seconds * 1000;
        const chunkMs = 100; // 每100ms检查一次取消
        let remainingMs = totalMs;

        while (remainingMs > 0) {
          checkCancellation();
          const sleepTime = Math.min(chunkMs, remainingMs);
          await sleep(sleepTime);
          remainingMs -= sleepTime;
        }
      }
    } else if (stmt.type === "CinStatement") {
      // 处理 cin 语句
      if (ioMethods && ioMethods.waitForInput) {
        for (const varName of stmt.variables) {
          // 检查是否是数组元素输入 (如 "a[i]")
          if (varName.includes('[') && varName.includes(']')) {
            // 解析数组元素：a[i] -> arrayName="a", index="i"
            const match = varName.match(/^([a-zA-Z_]\w*)\[([^\]]+)\]$/);
            if (match) {
              const arrayName = match[1];
              const indexStr = match[2];

              // 检查数组是否已声明
              if (!arrays[arrayName]) {
                throw new Error(`错误：数组 '${arrayName}' 未声明。请先使用 'int ${arrayName}[大小];' 声明数组。`);
              }

              // 正确处理索引 - 可能是变量引用
              let index;
              if (typeof indexStr === 'string' && /^[a-zA-Z_]\w*$/.test(indexStr)) {
                // 变量引用
                index = Math.floor(parseFloat(variables[indexStr] || 0));
              } else {
                // 直接数字
                index = Math.floor(parseFloat(indexStr));
              }

              // 检查索引是否在数组范围内
              if (index < 0 || index >= arrays[arrayName].length) {
                throw new Error(`错误：数组 '${arrayName}' 的索引 ${index} 超出范围 [0, ${arrays[arrayName].length - 1}]。`);
              }

              const inputValue = await ioMethods.waitForInput(false); // 不使用笔附近输入框，让系统根据模式决定
              // 尝试解析为数字，如果失败则作为字符串
              const numValue = parseFloat(inputValue);
              const value = isNaN(numValue) ? inputValue : numValue;

              // 设置数组元素值
              arrays[arrayName][index] = value;
            }
          } else {
            // 普通变量 - 检查是否已声明
            if (!(varName in variables)) {
              throw new Error(`错误：变量 '${varName}' 未声明。请先使用 'int ${varName};' 或 'int ${varName} = 初始值;' 声明变量。`);
            }

            const inputValue = await ioMethods.waitForInput(false); // 不使用笔附近输入框，让系统根据模式决定
            // 尝试解析为数字，如果失败则作为字符串
            const numValue = parseFloat(inputValue);
            const value = isNaN(numValue) ? inputValue : numValue;

            // 设置变量值
            variables[varName] = value;
          }
        }
      }
    } else if (stmt.type === "CinWinStatement") {
      // 处理 cinWin() 语句
      if (ioMethods && ioMethods.setInputMode) {
        ioMethods.setInputMode('window');
      }
    } else if (stmt.type === "CoutStatement") {
      // 处理 cout 语句
      if (ioMethods && ioMethods.outputToCout) {
        let output = '';
        let precision = 6; // 默认精度
        let floatFormat = 'default'; // 默认浮点数格式
        let hasOutput = false; // 标记是否已经有输出

        for (const expr of stmt.expressions) {
          if (expr.type === "endl") {
            output += '\n';
            hasOutput = true;
          } else if (expr.type === "setprecision") {
            precision = parseInt(expr.value);
          } else if (expr.type === "fixed") {
            floatFormat = 'fixed';
          } else if (expr.type === "scientific") {
            floatFormat = 'scientific';
          } else if (expr.type === "defaultfloat") {
            floatFormat = 'default';
          } else {
            // 处理普通表达式
            const value = evalExpression(expr);
            let formattedValue = '';
            
            if (typeof value === 'number') {
              // 根据格式和精度格式化数字
              if (floatFormat === 'fixed') {
                formattedValue = value.toFixed(precision);
              } else if (floatFormat === 'scientific') {
                formattedValue = value.toExponential(precision);
              } else {
                // 默认格式
                if (Number.isInteger(value)) {
                  formattedValue = value.toString();
                } else {
                  formattedValue = value.toPrecision(precision);
                }
              }
            } else {
              formattedValue = String(value);
            }
            
            // 直接连接输出，不添加空格分隔（符合C++标准行为）
            output += formattedValue;
            hasOutput = true;
          }
        }

        ioMethods.outputToCout(output);
      }
    } else if (stmt.type === "VariableDeclaration") {
      // 处理变量声明
      // 检查变量是否已经声明过
      if (Object.prototype.hasOwnProperty.call(variables, stmt.name)) {
        throw new Error(`错误：变量 '${stmt.name}' 已经定义。不能使用同一个变量名称重复定义。`);
      }
      
      let value;
      if (stmt.valueTokens) {
        // 新的格式：支持复杂表达式
        value = evalTokens(stmt.valueTokens);
      } else if (stmt.value) {
        // 旧的格式：简单值
        value = evalExpression(stmt.value);
      } else {
        // 根据数据类型设置默认值
        if (stmt.dataType === "double") {
          value = 0.0;
        } else {
          value = 0;
        }
      }
      
      // 根据数据类型进行类型转换
      if (stmt.dataType === "double") {
        value = parseFloat(value);
      } else {
        value = Math.trunc(parseFloat(value));
      }
      
      variables[stmt.name] = value;
      logger.log(`📝 变量声明: ${stmt.dataType || 'int'} ${stmt.name} = ${value}`);
    } else if (stmt.type === "MultipleVariableDeclaration") {
      // 处理多变量声明
      for (const varName of stmt.variables) {
        // 检查变量是否已经声明过
        if (Object.prototype.hasOwnProperty.call(variables, varName)) {
          throw new Error(`错误：变量 '${varName}' 已经定义。不能使用同一个变量名称重复定义。`);
        }
        variables[varName] = 0; // 默认初始化为0
        logger.log(`📝 变量声明: ${varName} = 0`);
      }
    } else if (stmt.type === "ArrayDeclaration") {
      // 处理数组声明
      // 检查数组是否已经声明过（检查变量和数组）
      if (Object.prototype.hasOwnProperty.call(variables, stmt.name)) {
        throw new Error(`错误：变量 '${stmt.name}' 已经定义。不能使用同一个变量名称重复定义。`);
      }
      if (Object.prototype.hasOwnProperty.call(arrays, stmt.name)) {
        throw new Error(`错误：数组 '${stmt.name}' 已经定义。不能使用同一个变量名称重复定义。`);
      }
      
      const size = Math.floor(parseFloat(stmt.size));
      arrays[stmt.name] = new Array(size).fill(0);

      // 记录数组声明的trace
      if (traceCollector) {
        const arrayDeclaration = `int ${stmt.name}[${size}]`;

        logger.log('🔍 Array声明trace调试:');
        logger.log('  stmt.name:', stmt.name, typeof stmt.name);
        logger.log('  size:', size, typeof size);
        logger.log('  arrayDeclaration:', arrayDeclaration);

        traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
        traceCollector.record('array', [arrayDeclaration], {
          declarationType: 'array',
          dataType: 'int',
          name: stmt.name,
          size: size,
          fullDeclaration: arrayDeclaration
        });
      }

      if (stmt.elements) {
        for (let i = 0; i < Math.min(stmt.elements.length, size); i++) {
          arrays[stmt.name][i] = evalExpression(stmt.elements[i]);
        }
      }
    } else if (stmt.type === "MixedDeclaration") {
      // 处理混合声明：int a[],n;
      // 先检查所有声明中是否有重复的变量名
      const declaredNames = new Set();
      for (const decl of stmt.declarations) {
        if (declaredNames.has(decl.name)) {
          throw new Error(`错误：变量 '${decl.name}' 在同一语句中重复定义。每个变量只能声明一次。`);
        }
        declaredNames.add(decl.name);
      }
      
      for (const decl of stmt.declarations) {
        if (decl.type === "VariableDeclaration") {
          // 处理普通变量声明
          // 检查变量是否已经声明过（检查变量和数组）
          if (Object.prototype.hasOwnProperty.call(variables, decl.name)) {
            throw new Error(`错误：变量 '${decl.name}' 已经定义。不能使用同一个变量名称重复定义。`);
          }
          if (Object.prototype.hasOwnProperty.call(arrays, decl.name)) {
            throw new Error(`错误：数组 '${decl.name}' 已经定义。不能使用同一个变量名称重复定义。`);
          }
          
          let value = 0;
          if (decl.valueTokens) {
            // 如果有初始化值，计算它
            try {
              value = evalTokens(decl.valueTokens);
            } catch (error) {
              value = 0;
            }
          }
          variables[decl.name] = value;
          logger.log(`📝 混合声明-变量: ${decl.name} = ${value}`);
        } else if (decl.type === "ArrayDeclaration") {
          // 处理数组声明
          // 检查数组是否已经声明过（检查变量和数组）
          if (Object.prototype.hasOwnProperty.call(variables, decl.name)) {
            throw new Error(`错误：变量 '${decl.name}' 已经定义。不能使用同一个变量名称重复定义。`);
          }
          if (Object.prototype.hasOwnProperty.call(arrays, decl.name)) {
            throw new Error(`错误：数组 '${decl.name}' 已经定义。不能使用同一个变量名称重复定义。`);
          }
          
          const size = Math.floor(parseFloat(decl.size));
          arrays[decl.name] = new Array(size).fill(0);
          logger.log(`📝 混合声明-数组: ${decl.name}[${size}]`);
          
          // 记录数组声明的trace
          if (traceCollector) {
            const arrayDeclaration = `int ${decl.name}[${size}]`;
            traceCollector.updateState({ x, y, angle, color: ctx.strokeStyle || 'black', lineWidth, isPenDown });
            traceCollector.record('array', [arrayDeclaration], {
              declarationType: 'array',
              dataType: 'int',
              name: decl.name,
              size: size,
              fullDeclaration: arrayDeclaration
            });
          }
        }
      }
    } else if (stmt.type === "VariableAssignment") {
      // 处理变量赋值
      const varName = stmt.name;
      const value = evalTokens(stmt.valueTokens);
      variables[varName] = value;
      logger.log(`📝 变量赋值: ${varName} = ${value}`);
    } else if (stmt.type === "ArrayAssignment") {
      // 处理数组赋值
      const arrayName = stmt.array;

      // 正确处理索引 - 可能是变量引用
      let index;
      if (typeof stmt.index === 'string' && /^[a-zA-Z_]\w*$/.test(stmt.index)) {
        // 变量引用
        if (!Object.prototype.hasOwnProperty.call(variables, stmt.index)) {
          throw new Error(`错误：变量 '${stmt.index}' 未定义。请先使用 'int ${stmt.index};' 或 'int ${stmt.index} = 初始值;' 声明变量。`);
        }
        const varValue = variables[stmt.index];
        index = Math.floor(parseFloat(varValue));
      } else {
        // 直接数字
        index = Math.floor(parseFloat(stmt.index));
      }

      // 正确处理值 - 可能是变量引用、数组访问或直接数字
      let value;
      if (typeof stmt.value === 'object' && stmt.value.type === 'ArrayAccess') {
        // 数组访问：a[i] = a[j];
        const sourceArrayName = stmt.value.array;
        let sourceIndex;
        if (typeof stmt.value.index === 'string' && /^[a-zA-Z_]\w*$/.test(stmt.value.index)) {
          // 变量引用
          if (!Object.prototype.hasOwnProperty.call(variables, stmt.value.index)) {
            throw new Error(`错误：变量 '${stmt.value.index}' 未定义。请先使用 'int ${stmt.value.index};' 或 'int ${stmt.value.index} = 初始值;' 声明变量。`);
          }
          const varValue = variables[stmt.value.index];
          sourceIndex = Math.floor(parseFloat(varValue));
        } else {
          // 直接数字
          sourceIndex = Math.floor(parseFloat(stmt.value.index));
        }
        
        if (arrays[sourceArrayName] && sourceIndex >= 0 && sourceIndex < arrays[sourceArrayName].length) {
          value = arrays[sourceArrayName][sourceIndex];
        } else {
          value = 0;
        }
      } else if (stmt.value.length === 1 && typeof stmt.value[0] === 'string' && /^[a-zA-Z_]\w*$/.test(stmt.value[0])) {
        // 变量引用
        if (!Object.prototype.hasOwnProperty.call(variables, stmt.value[0])) {
          throw new Error(`错误：变量 '${stmt.value[0]}' 未定义。请先使用 'int ${stmt.value[0]};' 或 'int ${stmt.value[0]} = 初始值;' 声明变量。`);
        }
        value = parseFloat(variables[stmt.value[0]]);
      } else {
        // 直接数字
        value = parseFloat(stmt.value[0]);
      }

      if (arrays[arrayName] && index >= 0 && index < arrays[arrayName].length) {
        arrays[arrayName][index] = value;
      }
    } else if (stmt.type === "ExpressionStatement") {
      //表达式语句（如 pen.fd(100).rt(90);）
      const parts = stmt.expression;
      
      // 首先检查是否是简单的递增递减运算符表达式
      if (parts.length === 2) {
        if (parts[1] === "++") {
          // 处理 a++
          const varName = parts[0];
          if (Object.prototype.hasOwnProperty.call(variables, varName)) {
            variables[varName] = (variables[varName] || 0) + 1;
            logger.log(`📝 递增运算符: ${varName}++ = ${variables[varName]}`);
            return; // 直接返回，不继续处理
          }
        } else if (parts[1] === "--") {
          // 处理 a--
          const varName = parts[0];
          if (Object.prototype.hasOwnProperty.call(variables, varName)) {
            variables[varName] = (variables[varName] || 0) - 1;
            logger.log(`📝 递减运算符: ${varName}-- = ${variables[varName]}`);
            return; // 直接返回，不继续处理
          }
        } else if (parts[0] === "++") {
          // 处理 ++a
          const varName = parts[1];
          if (Object.prototype.hasOwnProperty.call(variables, varName)) {
            variables[varName] = (variables[varName] || 0) + 1;
            logger.log(`📝 前置递增运算符: ++${varName} = ${variables[varName]}`);
            return; // 直接返回，不继续处理
          }
        } else if (parts[0] === "--") {
          // 处理 --a
          const varName = parts[1];
          if (Object.prototype.hasOwnProperty.call(variables, varName)) {
            variables[varName] = (variables[varName] || 0) - 1;
            logger.log(`📝 前置递减运算符: --${varName} = ${variables[varName]}`);
            return; // 直接返回，不继续处理
          }
        }
      }
      
      let obj = pen;

      // 首先进行语法验证：检查双点语法错误和无效连接符
      for (let i = 0; i < parts.length - 1; i++) {
        if ((parts[i] === "pen" || parts[i] === "p") && parts[i + 1] === "." && parts[i + 2] === ".") {
          throw new Error(`语法错误：'${parts[i]}..' 是无效语法。请使用 '${parts[i]}.方法名()' 而不是 '${parts[i]}..方法名()'。`);
        }
        
        // 检查无效连接符：pen命令后只能使用点号(.)连接
        if ((parts[i] === "pen" || parts[i] === "p") && parts[i + 1] !== "." && parts[i + 1] !== undefined) {
          const invalidConnector = parts[i + 1];
          const invalidConnectors = ['!', '#', '@', '$', '%', '^', '&', '*', '+', '=', '-', '_', '|', '\\', '/', '?', '~', '`', ':', ';', ',', '<', '>', '[', ']', '{', '}', '(', ')'];
          
          if (invalidConnectors.includes(invalidConnector)) {
            throw new Error(`语法错误：pen命令后不能使用 '${invalidConnector}' 作为连接符。请使用点号(.)连接`);
          }
        }
        
        // 检查链式调用中的无效连接符
        if (parts[i] === ")" && i + 1 < parts.length && parts[i + 1] !== "." && parts[i + 1] !== ";") {
          const invalidConnector = parts[i + 1];
          const invalidConnectors = ['!', '#', '@', '$', '%', '^', '&', '*', '+', '=', '-', '_', '|', '\\', '/', '?', '~', '`', ':', ',', '<', '>', '[', ']', '{', '}', '('];
          
          if (invalidConnectors.includes(invalidConnector)) {
            throw new Error(`语法错误：链式调用中不能使用 '${invalidConnector}' 作为连接符。请使用点号(.)连接，例如：pen.fd(100).rt(90) 而不是 pen.fd(100)${invalidConnector}rt(90)。`);
          }
        }
      }

      // 处理新的FunctionCall节点类型
      for (let i = 0; i < parts.length; i++) {
        if (parts[i] === "pen") continue;
        if (parts[i] === ".") continue;

        // 处理ArrayAccess节点
        if (typeof parts[i] === 'object' && parts[i].type === "ArrayAccess") {
          const arrayName = parts[i].array;

          // 正确处理索引 - 支持复杂表达式
          let index;
          if (typeof parts[i].index === 'object') {
            // 复杂表达式，需要递归计算
            index = Math.floor(parseFloat(evalExpression(parts[i].index)));
          } else if (typeof parts[i].index === 'string' && /^[a-zA-Z_]\w*$/.test(parts[i].index)) {
            // 变量引用
            index = Math.floor(parseFloat(variables[parts[i].index] || 0));
          } else {
            // 直接数字
            index = Math.floor(parseFloat(parts[i].index));
          }

          if (arrays[arrayName] && arrays[arrayName][index] !== undefined) {
            // 将数组访问结果替换为实际值，让后续处理继续
            const value = arrays[arrayName][index];
            parts[i] = value.toString();
          } else {
            // 如果数组不存在或索引无效，使用0
            parts[i] = "0";
          }
        }

        // 处理FunctionCall节点
        if (typeof parts[i] === 'object' && parts[i].type === "FunctionCall") {
          const funcName = parts[i].name;
          const args = parts[i].args;

          // 检查是否是pen对象的方法，如果是则必须通过pen.或p.前缀调用
          if (penMethods.includes(funcName)) {
            // 检查是否是通过pen.或p.前缀调用的
            let isPenMethodCall = false;
            for (let j = 0; j < i; j++) {
              if (parts[j] === "pen" || parts[j] === "p") {
                isPenMethodCall = true;
                break;
              }
            }
            
            if (!isPenMethodCall) {
              throw new Error(`错误：命令 '${funcName}' 是pen对象的方法，必须通过 'pen.${funcName}()' 或 'p.${funcName}()' 的形式调用，不能直接使用 '${funcName}()'。`);
            }
          }

          // 检查无参数命令的参数数量
          const noParamCommands = ['up', 'down', 'show', 'hide'];
          if (noParamCommands.includes(funcName) && args.length > 0) {
            throw new Error(`错误：命令 'pen.${funcName}' 不需要参数，但提供了 ${args.length} 个参数。请使用 'pen.${funcName}();' 而不是 'pen.${funcName}(参数);'。`);
          }

          // 计算参数值
          const argValues = args.map(arg => {
            if (typeof arg === 'object' && arg.type) {
              // 如果是表达式节点，计算其值
              return evalExpression(arg);
            } else {
              // 如果是简单值，直接返回
              return parseFloat(arg) || 0;
            }
          });

          if (typeof obj[funcName] === "function") {
            checkCancellation();
            const result = obj[funcName](...argValues);
            if (result instanceof Promise) {
              checkCancellation();
              await result;
            }
          }
          continue;
        }

        if (parts[i + 1] === "(") {
          // 解析多参数（支持嵌套括号与 + 拼接、d2s(expr)）
          const { inner, endIndex } = extractParenTokens(parts, i + 1);
          // 拆分逗号（顶层）
          let depth2 = 0;
          const argTokenLists = [];
          let cur = [];
          for (let k = 0; k < inner.length; k++) {
            const t = inner[k];
            if (t === '(') { depth2++; cur.push(t); continue; }
            if (t === ')') { depth2--; cur.push(t); continue; }
            if (t === ',' && depth2 === 0) { argTokenLists.push(cur); cur = []; continue; }
            cur.push(t);
          }
          argTokenLists.push(cur);
          const args = argTokenLists.map(evalArgTokens);
          
          // 检查是否是pen对象的方法，如果是则必须通过pen.或p.前缀调用
          if (penMethods.includes(parts[i])) {
            // 检查是否是通过pen.或p.前缀调用的
            let isPenMethodCall = false;
            for (let j = 0; j < i; j++) {
              if (parts[j] === "pen" || parts[j] === "p") {
                isPenMethodCall = true;
                break;
              }
            }
            
            if (!isPenMethodCall) {
              throw new Error(`错误：命令 '${parts[i]}' 是pen对象的方法，必须通过 'pen.${parts[i]}()' 或 'p.${parts[i]}()' 的形式调用，不能直接使用 '${parts[i]}()'。`);
            }
          }
          
          // 检查无参数命令的参数数量
          const noParamCommands = ['up', 'down', 'show', 'hide'];
          if (noParamCommands.includes(parts[i]) && args.length > 0) {
            throw new Error(`错误：命令 'pen.${parts[i]}' 不需要参数，但提供了 ${args.length} 个参数。请使用 'pen.${parts[i]}();' 而不是 'pen.${parts[i]}(参数);'。`);
          }
          
          // 检查必需参数命令的参数数量
          const requiredParamCommands = ['fd', 'bk', 'rt', 'lt', 'o', 'oo', 'e', 'ee', 'r', 'rr', 'c', 'size', 'text', 'moveTo', 'lineto', 'moveto'];
          if (requiredParamCommands.includes(parts[i])) {
            // 过滤掉空参数（只包含空字符串或空数组的参数）
            const validArgs = args.filter(arg => {
              if (typeof arg === 'string') return arg.trim() !== '';
              if (Array.isArray(arg)) return arg.length > 0;
              return true;
            });
            if (validArgs.length === 0) {
              throw new Error(`错误：命令 'pen.${parts[i]}' 需要参数，但没有提供参数。请使用 'pen.${parts[i]}(参数);' 而不是 'pen.${parts[i]}();'。`);
            }
            
            // 检查参数数量是否超出限制（基于函数定义的最大参数数）
            const maxParamLimits = {
              'fd': 1, 'bk': 1, 'rt': 1, 'lt': 1,
              'o': 2, 'oo': 2, 'e': 3, 'ee': 3, 'r': 3, 'rr': 3,
              'c': 1, 'size': 1, 'text': 3,
              'moveTo': 2, 'lineto': 2, 'moveto': 2
            };
            
            const maxParams = maxParamLimits[parts[i]];
            
            if (maxParams && validArgs.length > maxParams) {
              throw new Error(`错误：命令 'pen.${parts[i]}' 最多接受 ${maxParams} 个参数，但提供了 ${validArgs.length} 个参数。请检查参数数量是否正确。`);
            }
          }
          
          if (typeof obj[parts[i]] === "function") {
            checkCancellation();
            const result = obj[parts[i]](...args);
            if (result instanceof Promise) {
              checkCancellation();
              await result;
            }
          }
          i = endIndex; // 跳到右括号后
        }
      }

      // 工具：提取括号内的 tokens（支持嵌套）
      function extractParenTokens(tokens, startIdx) {
        // startIdx 指向 '('
        let depth = 0;
        const collected = [];
        let j = startIdx;
        while (j < tokens.length) {
          const t = tokens[j];
          if (t === '(') {
            if (depth > 0) collected.push(t);
            depth++;
          } else if (t === ')') {
            depth--;
            if (depth === 0) {
              // 结束在 j 位置，返回收集内容与 j
              return { inner: collected, endIndex: j };
            }
            collected.push(t);
          } else {
            collected.push(t);
          }
          j++;
        }
        return { inner: collected, endIndex: j };
      }

      // 工具：将 tokens（单个参数表达式）求值：支持字符串、数字、一元正负、加号拼接、d2s(expr)
      function evalArgTokens(tokens) {
        // 去除空 token
        const arr = tokens.filter(t => t !== undefined && t !== null);

        // 如果这是一个纯算术表达式（由 数字/变量/()+-*/% 组成），
        // 检查是否包含浮点数，如果包含则使用浮点数运算，否则使用整数运算
        const arithmeticOps = new Set(['+', '-', '*', '/', '%', '(', ')']);
        const isIdentifier = (s) => typeof s === 'string' && /^[a-zA-Z_]\w*$/.test(s);
        const isNumberToken = (s) => typeof s === 'string' && /^\d*(?:\.\d+)?$/.test(s) && s !== '';
        const isArithmeticToken = (s) => isNumberToken(s) || isIdentifier(s) || arithmeticOps.has(s);
        const containsOp = arr.some(t => arithmeticOps.has(t) && t !== '(' && t !== ')');
        const pureArithmetic = arr.length > 0 && arr.every(isArithmeticToken) && containsOp;
        
        if (pureArithmetic) {
          // 检查是否包含浮点数
          const containsFloat = arr.some(t => typeof t === 'string' && /^\d*\.\d+$/.test(t));
          if (containsFloat) {
            // 包含浮点数，使用浮点数运算
            return evalFloatExpression(arr);
          } else {
            // 纯整数运算，使用整数表达式求值，模拟 C 语言的整数运算与整除
            return evalSimpleExpression(arr);
          }
        }
        // 解析 d2s(expr)
        function tryD2S(ts) {
          if (ts[0] === 'd2s' && ts[1] === '(') {
            const { inner } = extractParenTokens(ts, 1);
            const val = evalArgTokens(inner);
            // 转为字符串
            return String(val);
          }
          return null;
        }
        // 解析 getX() / getY() 无参函数
        function tryGetXY(ts) {
          if ((ts[0] === 'getX' || ts[0] === 'getY') && ts[1] === '(') {
            const { inner } = extractParenTokens(ts, 1);
            if (inner.length === 0) {
              return ts[0] === 'getX' ? x : y;
            }
          }
          return null;
        }
        // 解析 rand()/rand(a,b) 返回整数
        function tryRand(ts) {
          if (ts[0] === 'rand' && ts[1] === '(') {
            const { inner } = extractParenTokens(ts, 1);
            // 拆分逗号（顶层）
            let depth = 0; const argsTok = []; let cur = [];
            for (let i = 0; i < inner.length; i++) {
              const t = inner[i];
              if (t === '(') { depth++; cur.push(t); continue; }
              if (t === ')') { depth--; cur.push(t); continue; }
              if (t === ',' && depth === 0) { argsTok.push(cur); cur = []; continue; }
              cur.push(t);
            }
            if (cur.length) argsTok.push(cur);
            if (argsTok.length === 0) {
              return Math.floor(Math.random() * 65536);
            }
            if (argsTok.length === 2) {
              const a = Number(evalArgTokens(argsTok[0]));
              const b = Number(evalArgTokens(argsTok[1]));
              if (Number.isFinite(a) && Number.isFinite(b)) {
                const min = Math.ceil(Math.min(a, b));
                const max = Math.floor(Math.max(a, b));
                const span = Math.max(0, max - min + 1);
                return min + Math.floor(Math.random() * (span || 1));
              }
            }
            return 0;
          }
          return null;
        }
        // 解析 pow(a,b) 返回浮点数
        function tryPow(ts) {
          if (ts[0] === 'pow' && ts[1] === '(') {
            const { inner } = extractParenTokens(ts, 1);
            let depth = 0; const argsTok = []; let cur = [];
            for (let i = 0; i < inner.length; i++) {
              const t = inner[i];
              if (t === '(') { depth++; cur.push(t); continue; }
              if (t === ')') { depth--; cur.push(t); continue; }
              if (t === ',' && depth === 0) { argsTok.push(cur); cur = []; continue; }
              cur.push(t);
            }
            if (cur.length) argsTok.push(cur);
            if (argsTok.length === 2) {
              const a = Number(evalArgTokens(argsTok[0]));
              const b = Number(evalArgTokens(argsTok[1]));
              if (Number.isFinite(a) && Number.isFinite(b)) {
                return Math.pow(a, b);
              }
            }
            return NaN;
          }
          return null;
        }
        // 拆分 + 号（仅顶层）
        let depth = 0;
        const parts = [];
        let current = [];
        for (let i = 0; i < arr.length; i++) {
          const t = arr[i];
          if (t === '(') { depth++; current.push(t); continue; }
          if (t === ')') { depth--; current.push(t); continue; }
          if (t === '+' && depth === 0) {
            parts.push(current); current = []; continue;
          }
          current.push(t);
        }
        parts.push(current);

        function evalPrimary(ts) {
          // 尝试 d2s()
          const d = tryD2S(ts);
          if (d !== null) return d;
          // 尝试 getX()/getY()
          const xy = tryGetXY(ts);
          if (xy !== null) return xy;
          // 尝试 rand()/rand(a,b)
          const r = tryRand(ts);
          if (r !== null) return r;
          // 尝试 pow(a,b)
          const p = tryPow(ts);
          if (p !== null) return p;
          // 字符串字面量 - 支持多个字符串token的情况
          // 检查是否包含中文双引号
          for (const t of ts) {
            if (typeof t === 'string' && (t.includes('“') || t.includes('”'))) {
              throw new Error(`错误：检测到中文双引号，请使用英文双引号 """。字符串必须使用英文双引号包裹。`);
            }
          }
          if (ts.length >= 1 && ts.every(t => typeof t === 'string' && t.startsWith('"') && t.endsWith('"'))) {
            // 所有token都是字符串字面量，连接它们
            return ts.map(t => t.slice(1, -1)).join('');
          }
          // 单个字符串字面量
          if (ts.length === 1 && typeof ts[0] === 'string' && ts[0].startsWith('"') && ts[0].endsWith('"')) {
            return ts[0].slice(1, -1);
          }
          // 处理ArrayAccess对象
          if (ts.length === 1 && typeof ts[0] === 'object' && ts[0].type === "ArrayAccess") {
            const arrayName = ts[0].array;

            // 正确处理索引 - 可能是变量引用
            let index;
            if (typeof ts[0].index === 'string' && /^[a-zA-Z_]\w*$/.test(ts[0].index)) {
              // 变量引用
              index = Math.floor(parseFloat(variables[ts[0].index] || 0));
            } else {
              // 直接数字
              index = Math.floor(parseFloat(ts[0].index));
            }

            if (arrays[arrayName] && arrays[arrayName][index] !== undefined) {
              const value = arrays[arrayName][index];
              return value;
            }
            return 0;
          }
          // 一元 +/- 数字 或 纯数字
          if (ts.length === 1) {
            const token = ts[0];
            if (/^\d*(?:\.\d+)?$/.test(token) && token !== '') return parseFloat(token);
            // 变量引用
            if (Object.prototype.hasOwnProperty.call(variables, token)) return variables[token];
          }
          // 数组访问：arr[0]
          if (ts.length >= 3 && ts[1] === '[') {
            const arrayName = ts[0];
            let bracketCount = 0;
            let indexTokens = [];
            for (let i = 2; i < ts.length; i++) {
              if (ts[i] === '[') bracketCount++;
              else if (ts[i] === ']') {
                if (bracketCount === 0) break;
                bracketCount--;
              }
              indexTokens.push(ts[i]);
            }
            const index = evalArgTokens(indexTokens);
            if (arrays[arrayName] && arrays[arrayName][Math.floor(index)] !== undefined) {
              return arrays[arrayName][Math.floor(index)];
            }
            return 0;
          }
          if (ts.length === 2 && (ts[0] === '-' || ts[0] === '+') && /^\d*(?:\.\d+)?$/.test(ts[1])) {
            return parseFloat(ts[0] + ts[1]);
          }
          // 括号包裹
          if (ts[0] === '(' && ts[ts.length - 1] === ')') {
            return evalArgTokens(ts.slice(1, -1));
          }
          // 兜底：拼接 token 为字符串
          return ts.join('');
        }

        // 若存在 +，则将各段转为字符串拼接
        if (parts.length > 1) {
          return parts.map(evalPrimary).map(v => String(v)).join('');
        }
        return evalPrimary(parts[0]);
      }

      for (let i = 0; i < parts.length; i++) {
        if (parts[i] === "pen") continue;
        if (parts[i] === ".") continue;

        // 处理ArrayAccess节点
        if (typeof parts[i] === 'object' && parts[i].type === "ArrayAccess") {
          const arrayName = parts[i].array;

          // 正确处理索引 - 支持复杂表达式
          let index;
          if (typeof parts[i].index === 'object') {
            // 复杂表达式，需要递归计算
            index = Math.floor(parseFloat(evalExpression(parts[i].index)));
          } else if (typeof parts[i].index === 'string' && /^[a-zA-Z_]\w*$/.test(parts[i].index)) {
            // 变量引用
            index = Math.floor(parseFloat(variables[parts[i].index] || 0));
          } else {
            // 直接数字
            index = Math.floor(parseFloat(parts[i].index));
          }

          if (arrays[arrayName] && arrays[arrayName][index] !== undefined) {
            // 将数组访问结果替换为实际值，让后续处理继续
            const value = arrays[arrayName][index];
            parts[i] = value.toString();
          } else {
            // 如果数组不存在或索引无效，使用0
            parts[i] = "0";
          }
        }

        if (parts[i + 1] === "(") {
          // 解析多参数（支持嵌套括号与 + 拼接、d2s(expr)）
          const { inner, endIndex } = extractParenTokens(parts, i + 1);
          // 拆分逗号（顶层）
          let depth2 = 0;
          const argTokenLists = [];
          let cur = [];
          for (let k = 0; k < inner.length; k++) {
            const t = inner[k];
            if (t === '(') { depth2++; cur.push(t); continue; }
            if (t === ')') { depth2--; cur.push(t); continue; }
            if (t === ',' && depth2 === 0) { argTokenLists.push(cur); cur = []; continue; }
            cur.push(t);
          }
          argTokenLists.push(cur);
          const args = argTokenLists.map(evalArgTokens);
          
          // 检查是否是pen对象的方法，如果是则必须通过pen.或p.前缀调用
          if (penMethods.includes(parts[i])) {
            // 检查是否是通过pen.或p.前缀调用的
            let isPenMethodCall = false;
            for (let j = 0; j < i; j++) {
              if (parts[j] === "pen" || parts[j] === "p") {
                isPenMethodCall = true;
                break;
              }
            }
            
            if (!isPenMethodCall) {
              throw new Error(`错误：命令 '${parts[i]}' 是pen对象的方法，必须通过 'pen.${parts[i]}()' 或 'p.${parts[i]}()' 的形式调用，不能直接使用 '${parts[i]}()'。`);
            }
          }
          
          // 检查无参数命令的参数数量
          const noParamCommands = ['up', 'down', 'show', 'hide'];
          if (noParamCommands.includes(parts[i]) && args.length > 0) {
            throw new Error(`错误：命令 'pen.${parts[i]}' 不需要参数，但提供了 ${args.length} 个参数。请使用 'pen.${parts[i]}();' 而不是 'pen.${parts[i]}(参数);'。`);
          }
          
          // 检查必需参数命令的参数数量
          const requiredParamCommands = ['fd', 'bk', 'rt', 'lt', 'o', 'oo', 'e', 'ee', 'r', 'rr', 'c', 'size', 'text', 'moveTo', 'lineto', 'moveto'];
          if (requiredParamCommands.includes(parts[i])) {
            // 过滤掉空参数（只包含空字符串或空数组的参数）
            const validArgs = args.filter(arg => {
              if (typeof arg === 'string') return arg.trim() !== '';
              if (Array.isArray(arg)) return arg.length > 0;
              return true;
            });
            if (validArgs.length === 0) {
              throw new Error(`错误：命令 'pen.${parts[i]}' 需要参数，但没有提供参数。请使用 'pen.${parts[i]}(参数);' 而不是 'pen.${parts[i]}();'。`);
            }
            
            // 检查参数数量是否超出限制（基于函数定义的最大参数数）
            const maxParamLimits = {
              'fd': 1, 'bk': 1, 'rt': 1, 'lt': 1,
              'o': 2, 'oo': 2, 'e': 3, 'ee': 3, 'r': 3, 'rr': 3,
              'c': 1, 'size': 1, 'text': 3,
              'moveTo': 2, 'lineto': 2, 'moveto': 2
            };
            
            const maxParams = maxParamLimits[parts[i]];
            
            if (maxParams && validArgs.length > maxParams) {
              throw new Error(`错误：命令 'pen.${parts[i]}' 最多接受 ${maxParams} 个参数，但提供了 ${validArgs.length} 个参数。请检查参数数量是否正确。`);
            }
          }
          
          if (typeof obj[parts[i]] === "function") {
            checkCancellation();
            const result = obj[parts[i]](...args);
            if (result instanceof Promise) {
              checkCancellation();
              await result;
            }
          }
          i = endIndex; // 跳到右括号后
        }
      }
    }
  }

  // 处理Program节点
  if (ast.type === "Program") {
    await Promise.all(ast.body.map(execStatement));
  } else {
    // 直接执行语句
    await execStatement(ast);
  }
}

export { execute }